From 8271fe48fd2c1430a058cb438210307f6d1e9622 Mon Sep 17 00:00:00 2001 From: TonyNa-code <278977922+TonyNa-code@users.noreply.github.com> Date: Tue, 13 Oct 2026 18:59:04 +0800 Subject: [PATCH 1/7] Add isolated Live2D companion preview and provider safeguards --- README.ja.md | 2 + README.md | 2 + README.zh-CN.md | 2 + docs/live2d.md | 79 +++++++ package.json | 2 +- scripts/privacy-check.js | 3 + src/chat-response.js | 7 +- src/chat.html | 1 + src/i18n.js | 90 ++++++++ src/index.html | 4 + src/live2d-bridge.js | 102 +++++++++ src/live2d-host.js | 71 +++++++ src/live2d-import.js | 181 ++++++++++++++++ src/live2d/index.html | 16 ++ src/live2d/vendor/CUBISM-FRAMEWORK-LICENSE.md | 45 ++++ src/live2d/vendor/NOTICE.md | 20 ++ src/live2d/vendor/PIXI-LICENSE.txt | 21 ++ src/live2d/vendor/PIXI-LIVE2D-LICENSE.txt | 21 ++ src/live2d/vendor/cubism4.min.js | 1 + src/live2d/vendor/pixi.min.js | 9 + src/live2d/viewer.css | 2 + src/live2d/viewer.js | 158 ++++++++++++++ src/main.js | 199 +++++++++++++----- src/network-safety.js | 61 ++++++ src/preload.js | 9 + src/quick-chat.html | 1 + src/renderer.js | 44 +++- src/settings.css | 10 + src/settings.html | 27 +++ src/settings.js | 79 ++++++- src/styles.css | 28 +++ tests/live2d-boot.cjs | 4 + tests/live2d-host.test.js | 45 ++++ tests/live2d-import.test.js | 74 +++++++ tests/live2d-runtime.test.js | 41 ++++ tests/live2d-smoke.cjs | 162 ++++++++++++++ tests/network-safety.test.js | 70 ++++++ tests/tts.test.js | 3 +- tests/voice-controls.test.js | 2 +- 39 files changed, 1634 insertions(+), 64 deletions(-) create mode 100644 docs/live2d.md create mode 100644 src/live2d-bridge.js create mode 100644 src/live2d-host.js create mode 100644 src/live2d-import.js create mode 100644 src/live2d/index.html create mode 100644 src/live2d/vendor/CUBISM-FRAMEWORK-LICENSE.md create mode 100644 src/live2d/vendor/NOTICE.md create mode 100644 src/live2d/vendor/PIXI-LICENSE.txt create mode 100644 src/live2d/vendor/PIXI-LIVE2D-LICENSE.txt create mode 100644 src/live2d/vendor/cubism4.min.js create mode 100644 src/live2d/vendor/pixi.min.js create mode 100644 src/live2d/viewer.css create mode 100644 src/live2d/viewer.js create mode 100644 src/network-safety.js create mode 100644 tests/live2d-boot.cjs create mode 100644 tests/live2d-host.test.js create mode 100644 tests/live2d-import.test.js create mode 100644 tests/live2d-runtime.test.js create mode 100644 tests/live2d-smoke.cjs create mode 100644 tests/network-safety.test.js diff --git a/README.ja.md b/README.ja.md index 5c95959..c818a5b 100644 --- a/README.ja.md +++ b/README.ja.md @@ -4,6 +4,8 @@ **0.4.0 音声操作の更新:**ペットのそばで読み上げを停止・再生でき、音声の準備・再生状態も確認できます。長い返信の固定文字数での打ち切りを解消しました。[更新内容](docs/releases/v0.4.0.md)。 +ローカルの **Live2D プレビュー**は公開版とは別にテスト中です。[モデル導入・互換性・利用条件](docs/live2d.md#日本語)。 + [![Build](https://github.com/TonyNa-code/desktop-pet/actions/workflows/build.yml/badge.svg)](https://github.com/TonyNa-code/desktop-pet/actions/workflows/build.yml) [![Latest Release](https://img.shields.io/github/v/release/TonyNa-code/desktop-pet?label=latest%20release)](https://github.com/TonyNa-code/desktop-pet/releases/latest) [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE) diff --git a/README.md b/README.md index 7539561..5493e7b 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ **0.4.0 voice controls:** stop or replay a reply beside the pet, see when voice is preparing or playing, and hear longer replies without the previous fixed cutoff. [Release notes](docs/releases/v0.4.0.md). +A local **Live2D preview** is being tested separately from the published release. [Model import, compatibility and licensing](docs/live2d.md). + [![Build](https://github.com/TonyNa-code/desktop-pet/actions/workflows/build.yml/badge.svg)](https://github.com/TonyNa-code/desktop-pet/actions/workflows/build.yml) [![Latest Release](https://img.shields.io/github/v/release/TonyNa-code/desktop-pet?label=latest%20release)](https://github.com/TonyNa-code/desktop-pet/releases/latest) [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE) diff --git a/README.zh-CN.md b/README.zh-CN.md index 7d7bbda..a9cfc1e 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -4,6 +4,8 @@ **0.4.0 语音互动更新:**桌宠旁即可停止朗读、重听回复,显示语音准备与播放状态,长回复不再固定截断。[更新说明](docs/releases/v0.4.0.md)。 +本地 **Live2D 预览功能**正在独立测试,尚未包含在正式发布版中。[模型导入、兼容性与许可说明](docs/live2d.md#简体中文)。 + [![Build](https://github.com/TonyNa-code/desktop-pet/actions/workflows/build.yml/badge.svg)](https://github.com/TonyNa-code/desktop-pet/actions/workflows/build.yml) [![Latest Release](https://img.shields.io/github/v/release/TonyNa-code/desktop-pet?label=latest%20release)](https://github.com/TonyNa-code/desktop-pet/releases/latest) [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE) diff --git a/docs/live2d.md b/docs/live2d.md new file mode 100644 index 0000000..a27bedd --- /dev/null +++ b/docs/live2d.md @@ -0,0 +1,79 @@ +# Live2D Preview + +[English](#english) | [简体中文](#简体中文) | [日本語](#日本語) + +## English + +This local experimental integration is not part of the published 0.4.0 release. Sprite characters remain available and keep their existing controls. + +### Import a Model + +1. Open **Companion Settings > Character > Import Live2D**. +2. Select a `.model3.json` file with its accompanying files still in their original folders, or a ZIP containing exactly one model. A `.moc3` file alone is not sufficient. +3. Confirm the import and select the new character. +4. For the first Live2D character, use **Download Core 5.2**, save the official `live2dcubismcore.min.js`, and choose it with **Install Core**. Only the recognized official file is accepted. Core is stored locally, not in the project. +5. Use the expression and motion menus to preview the model's own artwork. Assign its expressions to **Happy**, **Shy**, **Thoughtful** and **Sad**, then save. The default mapping is neutral because names such as `F01` have no universal meaning. + +**Click expression mode:** one click selects the next native expression, including neutral. Idle motions and pointer tracking stop; blinking and breathing continue. Double clicks and long presses do not start an automatic expression loop. Motion preview is unavailable in this mode. + +**Automatic mode:** subtle pointer tracking, local touch reactions and the model's idle motion at roughly 45-60 second intervals. A chat reply holds its assigned expression. Idle gestures pause while a reply is displayed or spoken. Turn off pointer tracking or interaction phrases independently in settings. + +**Voice:** external TTS audio drives mouth opening from its volume. This is not phoneme-level lip synchronization. System voices have no audio analyser and do not drive this mouth animation. A model needs mouth parameters for the effect to appear. + +For a closer companion tone, choose **Relationship > Partner**, set your preferred name, and describe the character's personality. Partner touch phrases remain local and make no model request. Affection, saved chat history and shared memories remain off by default. + +### Compatibility + +- Cubism 3/4 `.model3.json` exports with `.moc3`, PNG textures, `.exp3.json`, `.motion3.json`, physics and pose files. +- Some newer exports may work with Core 5.2, but this renderer does not promise all Cubism 5.x features. Cubism 5.3 extended blend modes, `.model.json`/Cubism 2, editable `.cmo3`, PSD, VRM and 3D models are not supported. +- Maximum 128 MiB per import, 256 files, 8 textures, 8192 pixels per texture dimension and 64 million total texture pixels. Each JSON file must be under 2 MiB. +- No embedded scripts, model audio, remote textures, external URLs or symbolic links are installed. Only the model's required files are copied. Removing a character does not delete its original folder. +- Animation quality depends on the rig and textures provided with the model. Importing a flat illustration does not create a rig. + +### Test Model and Terms + +The local test uses **Haru**, an official Live2D sample from [CubismWebSamples 4-r.7](https://github.com/Live2D/CubismWebSamples/tree/4-r.7/Samples/Resources/Haru), revision `de9eb4bec4326b81fe67a54e84322fdc39bc7446`. Haru is copyright Live2D Inc. and is available under the [Free Material License](https://www.live2d.com/eula/live2d-free-material-license-agreement_en.html), with the [sample model terms](https://www.live2d.com/eula/live2d-sample-model-terms_en.html). It is a test fixture, not a bundled character or a model covered by this repository's MIT license. + +Cubism Core is proprietary. The Framework also has its own license. User-loadable models bring additional publication considerations under the [official SDK guidance](https://help.live2d.com/zh-CHS/sdk/sdk_001/). The Live2D integration will not be included in a public release until its distribution terms are clarified. [Third-party notices](../src/live2d/vendor/NOTICE.md). + +### Privacy + +Imported models render in a separate sandboxed frame with no settings, chat history, API key or filesystem bridge. The frame only receives model selection, gesture controls and numeric audio levels. It cannot contact external servers. Model importing itself does not call an LLM or TTS service. + +Chat and spoken text still go to the services you explicitly configure. Returned TTS audio links must share the configured service's origin; redirects and cross-origin audio links are rejected. A provider using a separate CDN must return audio bytes/base64 directly or provide a same-origin audio endpoint. + +## 简体中文 + +这是尚未发布的本地实验功能,不在 GitHub 0.4.0 安装包中。原有图片桌宠和设置保持不变。 + +1. 打开 **陪伴设置 > 角色 > 导入 Live2D**,选择模型的 `.model3.json`,或仅含一个模型的 ZIP。纹理、动作等文件需保留原有目录结构;单独的 `.moc3` 无法使用。 +2. 确认导入并切换到新角色。首次使用时点 **下载 Core 5.2**,保存官方 `live2dcubismcore.min.js`,再通过 **安装 Core** 选择这个文件。程序只接受已核验的官方文件,运行库保存在本机数据目录。 +3. 预览模型自带的表情、动作,将合适的表情分配给开心、害羞、思考和难过,保存后随聊天回复变化。默认不猜测 `F01` 等名称的含义。 +4. 右键切换表情模式或人物大小。点击模式下一次点击换一个表情,不会变成自动轮播;眨眼和呼吸保留,注视和待机动作关闭。自动模式下才会有鼠标注视、触碰反应和低频待机动作,回复展示或朗读期间暂停待机动作。 +5. 外部 TTS 的实际音量可以驱动张嘴,停止朗读后收口。它不是逐音素口型;系统语音暂不驱动口型,模型也需要对应的嘴部参数。 + +想要更亲近的口吻,可以将人物关系设为 **恋人**,填写希望被称呼的名字和人物性格。恋人关系的触碰短句在本地运行,不调用 API。好感度、保存聊天记录、共同记忆依旧默认关闭。 + +支持 Cubism 3/4 导出的模型、PNG、表情、动作、物理和姿态文件。不能把一张立绘自动变成 Live2D,也不支持 Cubism 2、编辑工程 `.cmo3`、PSD、VRM 或 Cubism 5.3 的扩展混合模式。单包上限 128 MiB、256 文件、8 张纹理,单张最长边 8192,纹理总像素不超过 6400 万,单个 JSON 不超过 2 MiB。 + +测试使用的是官方 Haru 示例,版权属于 Live2D Inc.,不是 MIT 角色素材;下载来源和许可见上方链接。Core 也不是开源库。允许用户加载任意模型的应用涉及额外发布条款,完成核实前不会将本功能发布为正式安装包。 + +模型只在隔离窗口中接收动作参数和音量,不会拿到密钥、聊天记录或文件系统权限,也不能联网加载素材。导入不会覆盖原始文件。聊天和 TTS 仍只使用你配置的服务;服务返回的音频链接必须与服务地址同来源,否则应改为直接返回音频。 + +## 日本語 + +ローカルで試せる未公開機能です。公開版 0.4.0 には含まれていません。既存のスプライトキャラクターはそのまま使えます。 + +1. **付き添い設定 > キャラクター > Live2D を追加** から `.model3.json`、またはモデルが一つだけ入った ZIP を選びます。関連ファイルのフォルダー構成を保ってください。`.moc3` 単体では使えません。 +2. 追加したキャラクターを選択します。初回は **Core 5.2 をダウンロード** から公式の `live2dcubismcore.min.js` を保存し、**Core を導入** で選びます。確認済みの公式ファイルのみ受け付けます。 +3. 表情とモーションを試し、返答時の「うれしい・照れる・考え中・悲しい」に割り当てて保存します。`F01` などの意味はモデルごとに異なるため、初期値は自然な表情です。 +4. クリック表情モードでは一回のクリックで一つ進みます。自動切り替えや視線追従は止まりますが、まばたきと呼吸は続きます。自動モードの待機動作は低頻度で、返答表示中や読み上げ中は止まります。 +5. 外部 TTS の音量で口を動かします。音素単位のリップシンクではありません。システム音声は口の動きに対応していません。 + +関係を「恋人」にし、呼び名と性格を設定すると、会話やローカルの触れ合い短文も親しみのある口調になります。好感度、履歴保存、共通の記憶は初期状態では無効です。 + +Cubism 3/4 の書き出しモデルに対応します。Cubism 2、`.cmo3` 編集ファイル、PSD、VRM、Cubism 5.3 の拡張ブレンドは非対応です。128 MiB・256 ファイル・PNG 8 枚まで、各辺 8192 ピクセル以下、合計 6400 万ピクセル以下、JSON は一つ 2 MiB 以下です。 + +テストには Live2D Inc. の公式 Haru を使用しました。MIT 素材ではなく、上記の専用利用規約が適用されます。Core はプロプライエタリです。ユーザーモデルの読み込みに関する公開条件を確認するまでは、本機能を正式リリースに含めません。 + +モデルは設定・会話・API キー・ファイル操作の権限を持たない隔離フレームで表示され、外部通信もできません。会話と TTS だけは設定したサービスに送信されます。音声の返却リンクは TTS サービスと同一オリジンである必要があります。 diff --git a/package.json b/package.json index 02de3b4..9046601 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "scripts": { "start": "electron .", "dev": "electron . --dev", - "check": "node --check src/main.js && node --check src/i18n.js && node --check src/preload.js && node --check src/renderer.js && node --check src/chat.js && node --check src/quick-chat.js && node --check src/settings.js && node --check src/config-validation.js && node --check src/chat-response.js && node --check src/character-import.js && node --check src/speech-text.js && node --check src/voice-controls.js && npm test && node scripts/validate-assets.js && node scripts/privacy-check.js", + "check": "node --check src/main.js && node --check src/i18n.js && node --check src/preload.js && node --check src/renderer.js && node --check src/chat.js && node --check src/quick-chat.js && node --check src/settings.js && node --check src/config-validation.js && node --check src/chat-response.js && node --check src/character-import.js && node --check src/speech-text.js && node --check src/voice-controls.js && node --check src/network-safety.js && node --check src/live2d-import.js && node --check src/live2d-host.js && node --check src/live2d-bridge.js && node --check src/live2d/viewer.js && npm test && node scripts/validate-assets.js && node scripts/privacy-check.js", "test": "node --test tests/*.test.js", "test:smoke": "node tests/run-electron-smoke.cjs", "privacy:check": "node scripts/privacy-check.js", diff --git a/scripts/privacy-check.js b/scripts/privacy-check.js index f5446a4..d856691 100644 --- a/scripts/privacy-check.js +++ b/scripts/privacy-check.js @@ -25,6 +25,7 @@ const messagingArtifactPattern = [ const denyPatterns = [ { name: "macOS home path", pattern: /\/Users\/[^/\s]+/g }, + { name: "Linux home path", pattern: /\/home\/[^/\s]+/g }, { name: "macOS temporary path", pattern: /\/var\/folders\//g }, { name: "Windows home path", pattern: /C:\\Users\\[^\\/\s]+/gi }, { name: "messaging temporary artifact", pattern: new RegExp(`\\b(?:${messagingArtifactPattern})\\b`, "g") }, @@ -32,6 +33,8 @@ const denyPatterns = [ { name: "environment secret assignment", pattern: /\b(?:OPENAI_API_KEY|DEEPSEEK_API_KEY|ANTHROPIC_API_KEY)\s*=/g }, { name: "OpenAI-style secret", pattern: /\bsk-[A-Za-z0-9_-]{20,}\b/g }, { name: "bearer token", pattern: /\bBearer\s+[A-Za-z0-9._-]{24,}\b/g }, + { name: "GitHub token", pattern: /\b(?:gh[pousr]_[A-Za-z0-9]{30,}|github_pat_[A-Za-z0-9_]{30,})\b/g }, + { name: "private key block", pattern: /-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/g }, ]; function listGitFiles() { diff --git a/src/chat-response.js b/src/chat-response.js index d114c2d..269e353 100644 --- a/src/chat-response.js +++ b/src/chat-response.js @@ -1,8 +1,10 @@ // Handles both JSON responses and OpenAI-compatible SSE without retrying a paid request. +const { CHAT_LIMIT, readResponseJson } = require("./network-safety"); + async function readChatResponse(response, onProgress = () => {}) { const limit = 100000; if (!response.headers.get("content-type")?.includes("text/event-stream")) { - const data = await response.json(); + const data = await readResponseJson(response); const reply = data?.choices?.[0]?.message?.content; if (typeof reply !== "string" || reply.length > limit) throw new Error("invalid_reply"); return reply.trim(); @@ -13,6 +15,7 @@ async function readChatResponse(response, onProgress = () => {}) { let reply = ""; let complete = false; let finished = false; + let bytesRead = 0; function event(block) { const data = block.split("\n").filter((line) => line.startsWith("data:")) .map((line) => line.slice(5).replace(/^ /, "")).join("\n"); @@ -32,6 +35,8 @@ async function readChatResponse(response, onProgress = () => {}) { try { while (!complete) { const { value, done } = await reader.read(); + bytesRead += value?.byteLength || 0; + if (bytesRead > CHAT_LIMIT) throw new Error("response_too_large"); buffer += decoder.decode(value, { stream: !done }); // Keep a trailing CR until the next chunk, which may begin with LF. buffer = buffer.replace(/\r\n/g, "\n").replace(/\r(?!$)/g, "\n"); diff --git a/src/chat.html b/src/chat.html index d40aa3c..61f3293 100644 --- a/src/chat.html +++ b/src/chat.html @@ -2,6 +2,7 @@ + Companion Chat diff --git a/src/i18n.js b/src/i18n.js index 2bf948e..01d0782 100644 --- a/src/i18n.js +++ b/src/i18n.js @@ -16,6 +16,36 @@ const DICTIONARIES = { "zh-CN": { + "live2d.import": "导入 Live2D", + "live2d.loading": "角色载入中…", + "live2d.runtimeMissing": "尚未安装 Cubism Core。打开角色设置", + "live2d.loadFailed": "模型无法载入。打开角色设置", + "live2d.downloadCore": "下载 Core 5.2", + "live2d.importCore": "安装 Core", + "live2d.runtimeReady": "Core 已就绪", + "live2d.runtimeNeeded": "需要 Cubism Core 5.2", + "live2d.runtimeFailed": "文件不匹配,请选择官方 Core 5.2 文件", + "live2d.gaze": "自动模式下看向鼠标", + "live2d.expression": "表情", + "live2d.motion": "动作", + "live2d.previewExpression": "预览表情", + "live2d.previewMotion": "预览动作", + "live2d.replyExpressions": "回复表情", + "live2d.happy": "开心", + "live2d.shy": "害羞", + "live2d.review": "思考", + "live2d.failed": "难过", + "live2d.neutral": "自然表情", + "live2d.modelMeta": "{count} 个模型表情", + "live2d.actionFailed": "动作不可用;请检查当前角色和表情模式", + "tts.audioOrigin": "语音链接与服务地址不属于同一来源,请让服务直接返回音频或同来源链接。", + "tts.responseTooLarge": "语音响应过大,请缩短文本或调整服务输出。", + "pet.interaction.partner.head.0": "嗯……这样就很舒服。", + "pet.interaction.partner.head.1": "再陪我待一小会儿吧。", + "pet.interaction.partner.greet.0": "在呢,想和我说什么?", + "pet.interaction.partner.greet.1": "看到你过来,我有点开心。", + "pet.interaction.partner.drop.0": "好,就坐在你旁边。", + "pet.interaction.partner.drop.1": "这里不错,能离你近一点。", "settings.tabs.general": "通用", "settings.tabs.memory": "共同记忆", "settings.interactions": "互动短句(自动表情模式)", @@ -352,6 +382,36 @@ }, "en-US": { + "live2d.import": "Import Live2D", + "live2d.loading": "Loading character…", + "live2d.runtimeMissing": "Cubism Core is not installed. Open character settings", + "live2d.loadFailed": "Could not load this model. Open character settings", + "live2d.downloadCore": "Download Core 5.2", + "live2d.importCore": "Install Core", + "live2d.runtimeReady": "Core is ready", + "live2d.runtimeNeeded": "Cubism Core 5.2 required", + "live2d.runtimeFailed": "File mismatch. Choose the official Core 5.2 file", + "live2d.gaze": "Follow the pointer in automatic mode", + "live2d.expression": "Expression", + "live2d.motion": "Motion", + "live2d.previewExpression": "Preview expression", + "live2d.previewMotion": "Preview motion", + "live2d.replyExpressions": "Reply expressions", + "live2d.happy": "Happy", + "live2d.shy": "Shy", + "live2d.review": "Thoughtful", + "live2d.failed": "Sad", + "live2d.neutral": "Neutral", + "live2d.modelMeta": "{count} model expressions", + "live2d.actionFailed": "Action unavailable; check the character and expression mode", + "tts.audioOrigin": "The audio link must use the same origin as the voice service. Use direct audio or a same-origin link.", + "tts.responseTooLarge": "The voice response is too large. Shorten the text or adjust the service output.", + "pet.interaction.partner.head.0": "Mm… that's nice.", + "pet.interaction.partner.head.1": "Stay here with me a little?", + "pet.interaction.partner.greet.0": "I'm here. What's on your mind?", + "pet.interaction.partner.greet.1": "It's nice to see you over here.", + "pet.interaction.partner.drop.0": "Right here, beside you.", + "pet.interaction.partner.drop.1": "I like this spot. A little closer to you.", "settings.tabs.general": "General", "settings.tabs.memory": "Memories", "settings.interactions": "Touch responses (automatic expression mode)", @@ -688,6 +748,36 @@ }, "ja-JP": { + "live2d.import": "Live2D を追加", + "live2d.loading": "キャラクターを読み込み中…", + "live2d.runtimeMissing": "Cubism Core が未導入です。キャラクター設定を開く", + "live2d.loadFailed": "モデルを読み込めません。キャラクター設定を開く", + "live2d.downloadCore": "Core 5.2 をダウンロード", + "live2d.importCore": "Core を導入", + "live2d.runtimeReady": "Core の準備完了", + "live2d.runtimeNeeded": "Cubism Core 5.2 が必要です", + "live2d.runtimeFailed": "ファイルが一致しません。公式 Core 5.2 を選んでください", + "live2d.gaze": "自動モードでマウスを目で追う", + "live2d.expression": "表情", + "live2d.motion": "モーション", + "live2d.previewExpression": "表情を試す", + "live2d.previewMotion": "モーションを試す", + "live2d.replyExpressions": "返答時の表情", + "live2d.happy": "うれしい", + "live2d.shy": "照れる", + "live2d.review": "考え中", + "live2d.failed": "悲しい", + "live2d.neutral": "自然な表情", + "live2d.modelMeta": "表情 {count} 種類", + "live2d.actionFailed": "実行できません。キャラクターと表情モードを確認してください", + "tts.audioOrigin": "音声リンクはサービスと同じオリジンである必要があります。音声を直接返すか、同一オリジンのリンクを使用してください。", + "tts.responseTooLarge": "音声応答が大きすぎます。文章を短くするか、サービスの出力を調整してください。", + "pet.interaction.partner.head.0": "ん……気持ちいい。", + "pet.interaction.partner.head.1": "もう少し、一緒にいて?", + "pet.interaction.partner.greet.0": "いるよ。何か話したいことある?", + "pet.interaction.partner.greet.1": "こっちに来てくれて、ちょっとうれしい。", + "pet.interaction.partner.drop.0": "うん、隣にいるね。", + "pet.interaction.partner.drop.1": "ここ、いいね。少し近くにいられる。", "settings.tabs.general": "一般", "settings.tabs.memory": "思い出", "settings.interactions": "ふれあいの一言(自動表情モード)", diff --git a/src/index.html b/src/index.html index 062a666..61452ae 100644 --- a/src/index.html +++ b/src/index.html @@ -2,6 +2,7 @@ + Desktop Pet @@ -15,10 +16,13 @@ + + + diff --git a/src/live2d-bridge.js b/src/live2d-bridge.js new file mode 100644 index 0000000..3aefa1c --- /dev/null +++ b/src/live2d-bridge.js @@ -0,0 +1,102 @@ +(() => { + const ORIGIN = "pet-live2d://viewer"; + const CHANNEL = "desktop-pet-model"; + const stage = document.querySelector("#model-stage"); + const status = document.querySelector("#model-status"); + let frame; + let current; + let ready = false; + let ticket = 0; + let language = "en"; + let audioContext; + let audioSource; + let analyser; + let audioTimer; + let loadTimer; + + function send(type, extra = {}) { + if (frame && ready && current) frame.contentWindow.postMessage({ channel: CHANNEL, type, id: current.id, ...extra }, ORIGIN); + } + function message(key) { + status.textContent = window.DesktopPetI18n.t(key, {}, language); + status.hidden = !key; + } + function stopMouth() { + clearInterval(audioTimer); + audioSource?.disconnect(); + analyser?.disconnect(); + audioSource = analyser = null; + send("mouth", { value: 0 }); + } + async function attachAudio(audio) { + stopMouth(); + if (!current) return; + try { + audioContext ||= new AudioContext(); + await audioContext.resume(); + if (!current || audio.paused) return; + audioSource = audioContext.createMediaElementSource(audio); + analyser = audioContext.createAnalyser(); + analyser.fftSize = 512; + audioSource.connect(analyser); + analyser.connect(audioContext.destination); + const samples = new Float32Array(analyser.fftSize); + audioTimer = setInterval(() => { + if (!analyser) return; + analyser.getFloatTimeDomainData(samples); + const rms = Math.sqrt(samples.reduce((sum, value) => sum + value * value, 0) / samples.length); + send("mouth", { value: audio.paused || audio.ended ? 0 : Math.min(1, Math.max(0, (rms - 0.008) * 7)) }); + }, 40); + } catch { stopMouth(); } + } + async function apply(character, settings, busy = false) { + const next = character.type === "live2d" ? { + id: character.id, automatic: settings.expressionMode === "automatic", + gaze: settings.persona?.live2dGaze !== false, busy, + } : null; + language = settings.resolvedLanguage; + if (next && current?.id === next.id && frame) { + current = next; + send("options", next); + return; + } + const token = ++ticket; + stopMouth(); + clearTimeout(loadTimer); + frame?.remove(); frame = null; ready = false; + current = next; + stage.hidden = !next; + status.hidden = !next; + if (!next) return; + message("live2d.loading"); + try { + const runtime = await window.desktopPet.getLive2DRuntime(); + if (ticket !== token) return; + if (!runtime.ready) { message("live2d.runtimeMissing"); return; } + frame = document.createElement("iframe"); + frame.title = "Live2D"; + frame.setAttribute("sandbox", "allow-scripts allow-same-origin"); + frame.src = `${ORIGIN}/index.html`; + stage.replaceChildren(frame); + loadTimer = setTimeout(() => message("live2d.loadFailed"), 30000); + } catch { if (ticket === token) message("live2d.loadFailed"); } + } + window.addEventListener("message", (event) => { + if (!frame || event.source !== frame.contentWindow || event.origin !== ORIGIN || event.data?.channel !== CHANNEL) return; + if (event.data.type === "boot") { ready = true; send("load", current); } + if (event.data.type === "loaded") { clearTimeout(loadTimer); status.hidden = true; } + if (event.data.type === "error") { clearTimeout(loadTimer); message("live2d.loadFailed"); } + }); + window.desktopPet.onModelAction((action) => { + if (current?.id === action.id) send(action.type, { index: action.index, group: action.group }); + }); + status.addEventListener("click", () => window.desktopPet.openCompanionSettings()); + window.DesktopPetModel = { + apply, attachAudio, stopMouth, + cycle: () => send("cycle"), + expression: (index) => send("expression", { index }), + touch: () => send("touch"), + gaze: (x, y) => send("gaze", { x, y }), + busy: (busy) => { if (current) { current.busy = busy; send("options", current); } }, + }; +})(); diff --git a/src/live2d-host.js b/src/live2d-host.js new file mode 100644 index 0000000..1052aa7 --- /dev/null +++ b/src/live2d-host.js @@ -0,0 +1,71 @@ +const fs = require("node:fs"); +const path = require("node:path"); +const { createHash } = require("node:crypto"); +const { readLocal, resourceName } = require("./live2d-import"); + +const ORIGIN = "pet-live2d://viewer"; +const CORE_URL = "https://cubism.live2d.com/sdk-web/core/05/live2dcubismcore.min.js"; +const CORE_SHA256 = "25ae938cb4fe282ce189b357bcc97e603d1e1f7ec78bf04150d401c23cdc792f"; +const CORE_LIMIT = 4 * 1024 * 1024; +const POLICY = "default-src 'none'; script-src 'self' 'unsafe-eval' 'wasm-unsafe-eval'; style-src 'self'; img-src 'self' data: blob:; connect-src 'self'; media-src 'none'; object-src 'none'; base-uri 'none'; form-action 'none'; frame-src 'none'"; + +function corePath(userData) { return path.join(userData, "live2d-runtime", "live2dcubismcore.min.js"); } +function validCore(bytes) { + return bytes.length <= CORE_LIMIT && createHash("sha256").update(bytes).digest("hex") === CORE_SHA256; +} +function runtimeReady(userData) { + try { return validCore(readLocal(path.dirname(corePath(userData)), path.basename(corePath(userData)), CORE_LIMIT)); } + catch { return false; } +} +function installCore(source, userData) { + const stat = fs.lstatSync(source); + if (stat.isSymbolicLink() || !stat.isFile() || stat.size > CORE_LIMIT) throw new Error("invalid_runtime"); + const bytes = fs.readFileSync(source); + if (!validCore(bytes)) throw new Error("unrecognized_runtime"); + const target = corePath(userData); + fs.mkdirSync(path.dirname(target), { recursive: true }); + fs.writeFileSync(`${target}.tmp`, bytes); + fs.renameSync(`${target}.tmp`, target); +} + +function createModelHandler({ userData, sourceDir, getActiveCharacter }) { + const viewerFiles = new Map([ + ["/index.html", ["index.html", "text/html"]], + ["/viewer.js", ["viewer.js", "text/javascript"]], + ["/viewer.css", ["viewer.css", "text/css"]], + ["/pixi.min.js", ["vendor/pixi.min.js", "text/javascript"]], + ["/cubism4.min.js", ["vendor/cubism4.min.js", "text/javascript"]], + ]); + return (request) => { + const headers = { "Content-Security-Policy": POLICY, "X-Content-Type-Options": "nosniff", "Cache-Control": "no-store" }; + try { + const url = new URL(request.url); + if (url.protocol !== "pet-live2d:" || url.hostname !== "viewer" || url.port || url.username || url.password + || url.search || request.method !== "GET") throw new Error(); + let bytes; + let mime; + if (viewerFiles.has(url.pathname)) { + const [file, type] = viewerFiles.get(url.pathname); + bytes = readLocal(path.join(sourceDir, "live2d"), file, 8 * 1024 * 1024); mime = type; + } else if (url.pathname === "/core.js") { + bytes = readLocal(path.dirname(corePath(userData)), path.basename(corePath(userData)), CORE_LIMIT); + if (!validCore(bytes)) throw new Error(); + mime = "text/javascript"; + } else { + const match = /^\/models\/(imported-[a-f0-9]{24})\/(.+)$/.exec(url.pathname); + const pack = getActiveCharacter(); + if (!match || pack?.type !== "live2d" || pack.id !== match[1]) throw new Error(); + const name = resourceName(decodeURIComponent(match[2])); + const root = path.join(userData, "characters", pack.id); + const manifest = JSON.parse(readLocal(root, "character.json", 262144).toString("utf8")); + if (!Array.isArray(manifest.resources) || !manifest.resources.includes(name)) throw new Error(); + mime = name.endsWith(".png") ? "image/png" : name.endsWith(".json") ? "application/json" : name.endsWith(".moc3") ? "application/octet-stream" : null; + if (!mime) throw new Error(); + bytes = readLocal(root, name, 128 * 1024 * 1024); + } + return new Response(bytes, { headers: { ...headers, "Content-Type": mime } }); + } catch { return new Response("Unavailable", { status: 404, headers }); } + }; +} + +module.exports = { ORIGIN, CORE_URL, CORE_SHA256, POLICY, validCore, runtimeReady, installCore, createModelHandler }; diff --git a/src/live2d-import.js b/src/live2d-import.js new file mode 100644 index 0000000..ff92730 --- /dev/null +++ b/src/live2d-import.js @@ -0,0 +1,181 @@ +const fs = require("node:fs"); +const path = require("node:path"); +const { createHash } = require("node:crypto"); +const { unzipSync } = require("fflate"); +const { pngSize } = require("./character-import"); + +const MAX_BYTES = 128 * 1024 * 1024; +const MAX_FILES = 256; +const MAX_JSON = 2 * 1024 * 1024; + +function resourceName(value) { + if (typeof value !== "string" || !value || value.length > 240 + || /[\\:%?#\x00-\x1f\x7f]/.test(value) || value.startsWith("/")) throw new Error("invalid_path"); + const parts = value.split("/"); + if (parts.length > 10 || parts.some((part) => !part || part === "." || part === ".." + || /[. ]$/.test(part) || /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\.|$)/i.test(part))) throw new Error("invalid_path"); + return value; +} + +function readLocal(root, name, limit) { + const parts = resourceName(name).split("/"); + let current = root; + for (const part of parts) { + current = path.join(current, part); + if (fs.lstatSync(current).isSymbolicLink()) throw new Error("symlink"); + } + const stat = fs.statSync(current); + if (!stat.isFile() || stat.size > limit) throw new Error("invalid_size"); + return fs.readFileSync(current); +} + +function readJson(bytes) { + if (!bytes || bytes.length > MAX_JSON) throw new Error("invalid_json"); + const value = JSON.parse(Buffer.from(bytes).toString("utf8")); + const pending = [[value, 0]]; + let count = 0; + while (pending.length) { + const [item, depth] = pending.pop(); + if (++count > 150000 || depth > 24) throw new Error("complex_json"); + if (item && typeof item === "object") { + for (const [key, child] of Object.entries(item)) { + if (["__proto__", "constructor", "prototype"].includes(key)) throw new Error("invalid_json"); + pending.push([child, depth + 1]); + } + } + } + return value; +} + +function readLive2DPack(source, decodeImage) { + const stat = fs.lstatSync(source); + if (stat.isSymbolicLink()) throw new Error("symlink"); + let modelName; + let read; + if (stat.isFile() && source.endsWith(".zip")) { + if (stat.size > MAX_BYTES) throw new Error("archive_too_large"); + let total = 0; + let count = 0; + const seen = new Set(); + const zip = unzipSync(fs.readFileSync(source), { filter(entry) { + const name = entry.name.replace(/\/$/, ""); + resourceName(name); + const folded = name.normalize("NFC").toLowerCase(); + if (seen.has(folded) || ++count > MAX_FILES) throw new Error("invalid_archive"); + seen.add(folded); + if (!Number.isSafeInteger(entry.originalSize) || entry.originalSize < 0) throw new Error("invalid_size"); + total += entry.originalSize; + if (total > MAX_BYTES || (/\.json$/i.test(name) && entry.originalSize > MAX_JSON)) throw new Error("archive_too_large"); + return /\.(moc3|png|json)$/i.test(name); + } }); + const models = Object.keys(zip).filter((name) => name.endsWith(".model3.json")); + if (models.length !== 1) throw new Error("model_count"); + const prefix = models[0].slice(0, models[0].lastIndexOf("/") + 1); + modelName = models[0].slice(prefix.length); + read = (name, limit) => { + const bytes = zip[prefix + resourceName(name)]; + if (!bytes || bytes.length > limit) throw new Error("missing_resource"); + return Buffer.from(bytes); + }; + } else { + let root = source; + if (stat.isFile() && source.endsWith(".model3.json")) { + root = path.dirname(source); + modelName = path.basename(source); + } else if (stat.isDirectory()) { + const models = fs.readdirSync(root).filter((name) => name.endsWith(".model3.json")); + if (models.length !== 1) throw new Error("model_count"); + modelName = models[0]; + } else throw new Error("invalid_model"); + read = (name, limit) => readLocal(root, name, limit); + } + + const raw = readJson(read(modelName, MAX_JSON)); + const refs = raw.FileReferences; + if (raw.Version !== 3 || !refs || !Array.isArray(refs.Textures) + || !refs.Textures.length || refs.Textures.length > 8) throw new Error("invalid_model"); + const files = Object.create(null); + let bytesUsed = 0; + let pixels = 0; + const add = (name, extension) => { + resourceName(name); + if (!name.endsWith(extension)) throw new Error("invalid_resource"); + if (files[name]) return name; + const bytes = read(name, extension.endsWith("json") ? MAX_JSON : MAX_BYTES); + bytesUsed += bytes.length; + if (bytesUsed > MAX_BYTES || Object.keys(files).length >= MAX_FILES) throw new Error("model_too_large"); + if (extension === ".png") { + const size = pngSize(bytes); + pixels += size.width * size.height; + if (size.width > 8192 || size.height > 8192 || pixels > 64000000) throw new Error("image_too_large"); + if (decodeImage && !decodeImage(bytes)) throw new Error("image_decode_failed"); + } else if (extension.endsWith("json")) readJson(bytes); + files[name] = bytes; + return name; + }; + const cleanRefs = { Moc: add(refs.Moc, ".moc3"), Textures: refs.Textures.map((name) => add(name, ".png")) }; + if (files[cleanRefs.Moc].length < 64 || files[cleanRefs.Moc].subarray(0, 4).toString() !== "MOC3") throw new Error("invalid_moc"); + for (const key of ["Physics", "Pose"]) if (refs[key]) cleanRefs[key] = add(refs[key], key === "Physics" ? ".physics3.json" : ".pose3.json"); + if (refs.Expressions !== undefined) { + if (!Array.isArray(refs.Expressions) || refs.Expressions.length > 64) throw new Error("invalid_expressions"); + cleanRefs.Expressions = refs.Expressions.map((entry, index) => ({ + Name: String(entry.Name || `Expression ${index + 1}`).slice(0, 80), File: add(entry.File, ".exp3.json"), + })); + } + cleanRefs.Motions = {}; + if (refs.Motions !== undefined) { + if (!refs.Motions || Array.isArray(refs.Motions) || typeof refs.Motions !== "object" + || Object.keys(refs.Motions).length > 32) throw new Error("invalid_motions"); + for (const [group, motions] of Object.entries(refs.Motions)) { + if (group.length > 80 || !Array.isArray(motions) || motions.length > 64) throw new Error("invalid_motions"); + cleanRefs.Motions[group] = motions.map((entry) => { + // Model audio is deliberately excluded: only the user's TTS may speak. + const result = { File: add(entry.File, ".motion3.json") }; + for (const key of ["FadeInTime", "FadeOutTime"]) if (Number.isFinite(entry[key])) result[key] = Math.min(10, Math.max(0, entry[key])); + return result; + }); + } + } + const model = { Version: 3, FileReferences: cleanRefs }; + if (raw.Groups) { + if (!Array.isArray(raw.Groups) || raw.Groups.length > 8) throw new Error("invalid_groups"); + model.Groups = raw.Groups.filter((group) => group.Target === "Parameter" && ["EyeBlink", "LipSync"].includes(group.Name)) + .map((group) => ({ Target: "Parameter", Name: group.Name, + Ids: Array.isArray(group.Ids) ? group.Ids.slice(0, 64).filter((id) => typeof id === "string" && id.length <= 80) : [] })); + } + if (raw.Layout && typeof raw.Layout === "object") { + model.Layout = Object.fromEntries(Object.entries(raw.Layout).filter(([key, value]) => + ["CenterX", "CenterY", "X", "Y", "Width", "Height", "Top", "Bottom", "Left", "Right"].includes(key) + && Number.isFinite(value) && Math.abs(value) <= 100)); + } + // Only this reconstructed resource graph is installed; no scripts, URLs or unrelated files. + files["model.model3.json"] = Buffer.from(JSON.stringify(model)); + const digest = createHash("sha256"); + for (const name of Object.keys(files).sort()) digest.update(name).update(files[name]); + const manifest = { + schemaVersion: 1, type: "live2d", id: `imported-${digest.digest("hex").slice(0, 24)}`, + name: modelName.replace(/\.model3\.json$/, "").slice(0, 80), description: "", + model: "model.model3.json", resources: Object.keys(files), + expressions: (cleanRefs.Expressions || []).map((item) => item.Name), + motions: Object.fromEntries(Object.entries(cleanRefs.Motions).map(([group, items]) => [group, items.length])), + }; + return { manifest, files }; +} + +function installLive2DPack(pack, root) { + const target = path.join(root, pack.manifest.id); + if (fs.existsSync(target)) return; + fs.mkdirSync(root, { recursive: true }); + const staging = fs.mkdtempSync(path.join(root, ".import-")); + try { + for (const [name, bytes] of Object.entries(pack.files)) { + const dest = path.join(staging, resourceName(name)); + fs.mkdirSync(path.dirname(dest), { recursive: true }); + fs.writeFileSync(dest, bytes); + } + fs.writeFileSync(path.join(staging, "character.json"), JSON.stringify(pack.manifest, null, 2)); + fs.renameSync(staging, target); + } finally { fs.rmSync(staging, { recursive: true, force: true }); } +} + +module.exports = { readLive2DPack, installLive2DPack, resourceName, readLocal, MAX_BYTES }; diff --git a/src/live2d/index.html b/src/live2d/index.html new file mode 100644 index 0000000..21c4bcd --- /dev/null +++ b/src/live2d/index.html @@ -0,0 +1,16 @@ + + + + + + Character + + + + + + + + + + diff --git a/src/live2d/vendor/CUBISM-FRAMEWORK-LICENSE.md b/src/live2d/vendor/CUBISM-FRAMEWORK-LICENSE.md new file mode 100644 index 0000000..bd0be75 --- /dev/null +++ b/src/live2d/vendor/CUBISM-FRAMEWORK-LICENSE.md @@ -0,0 +1,45 @@ +## Definitions + +### Live2D Cubism Components + +Cubism Web Framework is included in Live2D Cubism Components. + +Cubism Web Framework は Live2D Cubism Components に含まれます。 + +Cubism Web Framework 包括在 Live2D Cubism Components 中。 + +## Cubism SDK Release License + +*All business* users must obtain a Cubism SDK Release License. "Business" means an entity with the annual gross revenue more than ten million (10,000,000) JPY for the most recent fiscal year. + +* [Cubism SDK Release License](https://www.live2d.com/en/download/cubism-sdk/release-license/) + +直近会計年度の売上高が 1000 万円以上の事業者様がご利用になる場合は、Cubism SDK リリースライセンス(出版許諾契約)に同意していただく必要がございます。 + +* [Cubism SDK リリースライセンス](https://www.live2d.com/ja/download/cubism-sdk/release-license/) + +如果您的企业在最近一个会计年度的销售额达到或超过1000万日元,您必须得到Cubism SDK的出版授权许可(出版许可协议)。 + +* [Cubism SDK发行许可证](https://www.live2d.com/zh-CHS/download/cubism-sdk/release-license/) + +## Live2D Open Software License + +Live2D Cubism Components is available under Live2D Open Software License. + +* [Live2D Open Software License](https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html) +* [Live2D Open Software 使用許諾契約書](https://www.live2d.com/eula/live2d-open-software-license-agreement_jp.html) +* [Live2D Open Software 使用授权协议](https://www.live2d.com/eula/live2d-open-software-license-agreement_cn.html) + + +## Live2D Proprietary Software License + +Live2D Cubism Core is available under Live2D Proprietary Software License. + +* [Live2D Proprietary Software License Agreement](https://www.live2d.com/eula/live2d-proprietary-software-license-agreement_en.html) +* [Live2D Proprietary Software 使用許諾契約書](https://www.live2d.com/eula/live2d-proprietary-software-license-agreement_jp.html) +* [Live2D Proprietary Software 使用授权协议](https://www.live2d.com/eula/live2d-proprietary-software-license-agreement_cn.html) + + +--- + +Please contact us from [here](https://www.live2d.jp/contact/) for more license information. diff --git a/src/live2d/vendor/NOTICE.md b/src/live2d/vendor/NOTICE.md new file mode 100644 index 0000000..01a9044 --- /dev/null +++ b/src/live2d/vendor/NOTICE.md @@ -0,0 +1,20 @@ +# Third-Party Runtime Notices + +These files are unmodified browser distributions. They are served locally; no CDN is contacted at runtime. + +| File | Version | Source | SHA-256 | +| --- | --- | --- | --- | +| `pixi.min.js` | PixiJS 6.5.10 | https://cdn.jsdelivr.net/npm/pixi.js@6.5.10/dist/browser/pixi.min.js | `403f2f2ee8145fa17f60c5c89403056efe2680e5096ec2762036486914ed19c5` | +| `cubism4.min.js` | pixi-live2d-display 0.4.0 | https://cdn.jsdelivr.net/npm/pixi-live2d-display@0.4.0/dist/cubism4.min.js | `af1267e6d52759b245766c578d905bfa025b532d5c3cc727c370957c4409e21b` | + +PixiJS is MIT licensed, copyright its contributors. See `PIXI-LICENSE.txt`. + +pixi-live2d-display is MIT licensed, copyright Guan. See `PIXI-LIVE2D-LICENSE.txt`. + +The Cubism display bundle also contains Live2D Cubism Framework components, copyright Live2D Inc., under the [Live2D Open Software License](https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html). See the upstream `CUBISM-FRAMEWORK-LICENSE.md` notice. The surrounding library's MIT license does not replace Live2D's terms. + +Cubism Core is proprietary and is not included. The optional local importer recognizes the official Core 5.2 file at https://cubism.live2d.com/sdk-web/core/05/live2dcubismcore.min.js, SHA-256 `25ae938cb4fe282ce189b357bcc97e603d1e1f7ec78bf04150d401c23cdc792f`. Its use is subject to the [Live2D Proprietary Software License](https://www.live2d.com/eula/live2d-proprietary-software-license-agreement_en.html). + +An application which loads user-supplied models may fall within Live2D's expandable-application rules. A free application or an MIT source repository is not itself proof of a publication exemption. See the [official SDK licensing guidance](https://help.live2d.com/zh-CHS/sdk/sdk_001/). Public distribution of this experimental integration is pending licensing clarification. + +No Live2D sample or user model is included in this directory or in the application's character assets. diff --git a/src/live2d/vendor/PIXI-LICENSE.txt b/src/live2d/vendor/PIXI-LICENSE.txt new file mode 100644 index 0000000..d9de993 --- /dev/null +++ b/src/live2d/vendor/PIXI-LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2013-2017 Mathew Groves, Chad Engler + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +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. diff --git a/src/live2d/vendor/PIXI-LIVE2D-LICENSE.txt b/src/live2d/vendor/PIXI-LIVE2D-LICENSE.txt new file mode 100644 index 0000000..dbc2166 --- /dev/null +++ b/src/live2d/vendor/PIXI-LIVE2D-LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Guan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +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. diff --git a/src/live2d/vendor/cubism4.min.js b/src/live2d/vendor/cubism4.min.js new file mode 100644 index 0000000..f0e4a50 --- /dev/null +++ b/src/live2d/vendor/cubism4.min.js @@ -0,0 +1 @@ +var __pow=Math.pow,__async=(t,e,i)=>new Promise(((s,r)=>{var a=t=>{try{n(i.next(t))}catch(e){r(e)}},o=t=>{try{n(i.throw(t))}catch(e){r(e)}},n=t=>t.done?s(t.value):Promise.resolve(t.value).then(a,o);n((i=i.apply(t,e)).next())}));!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("@pixi/utils"),require("@pixi/math"),require("@pixi/core"),require("@pixi/display")):"function"==typeof define&&define.amd?define(["exports","@pixi/utils","@pixi/math","@pixi/core","@pixi/display"],e):e(((t="undefined"!=typeof globalThis?globalThis:t||self).PIXI=t.PIXI||{},t.PIXI.live2d=t.PIXI.live2d||{}),t.PIXI.utils,t.PIXI,t.PIXI,t.PIXI)}(this,(function(t,e,i,s,r){"use strict";class a{constructor(){this._breathParameters=[],this._currentTime=0}static create(){return new a}setParameters(t){this._breathParameters=t}getParameters(){return this._breathParameters}updateParameters(t,e){this._currentTime+=e;const i=2*this._currentTime*3.14159;for(let s=0;s=1&&(s=1,this._blinkingState=h.EyeState_Closed,this._stateStartTimeSeconds=this._userTimeSeconds),i=1-s;break;case h.EyeState_Closed:s=(this._userTimeSeconds-this._stateStartTimeSeconds)/this._closedSeconds,s>=1&&(this._blinkingState=h.EyeState_Opening,this._stateStartTimeSeconds=this._userTimeSeconds),i=0;break;case h.EyeState_Opening:s=(this._userTimeSeconds-this._stateStartTimeSeconds)/this._openingSeconds,s>=1&&(s=1,this._blinkingState=h.EyeState_Interval,this._nextBlinkingTime=this.determinNextBlinkingTiming()),i=s;break;case h.EyeState_Interval:this._nextBlinkingTime(t[t.EyeState_First=0]="EyeState_First",t[t.EyeState_Interval=1]="EyeState_Interval",t[t.EyeState_Closing=2]="EyeState_Closing",t[t.EyeState_Closed=3]="EyeState_Closed",t[t.EyeState_Opening=4]="EyeState_Opening",t))(h||{});class u{static create(t){const e=new u;"number"==typeof t.FadeInTime&&(e._fadeTimeSeconds=t.FadeInTime,e._fadeTimeSeconds<=0&&(e._fadeTimeSeconds=.5));const i=t.Groups,s=i.length;for(let r=0;r.001){if(r>=0)break;r=n,a=t.getPartOpacityByIndex(i),a+=e/this._fadeTimeSeconds,a>1&&(a=1)}}r<0&&(r=0,a=1);for(let n=i;n.15&&(i=1-.15/(1-a)),s>i&&(s=i),t.setPartOpacityByIndex(e,s)}}}constructor(){this._fadeTimeSeconds=.5,this._lastModel=void 0,this._partGroups=[],this._partGroupCounts=[]}}class d{constructor(t){this.parameterIndex=0,this.partIndex=0,this.partId="",this.link=[],null!=t&&this.assignment(t)}assignment(t){return this.partId=t.partId,this.link=t.link.map((t=>t.clone())),this}initialize(t){this.parameterIndex=t.getParameterIndex(this.partId),this.partIndex=t.getPartIndex(this.partId),t.setParameterValueByIndex(this.parameterIndex,1)}clone(){const t=new d;return t.partId=this.partId,t.parameterIndex=this.parameterIndex,t.partIndex=this.partIndex,t.link=this.link.map((t=>t.clone())),t}}class c{constructor(t,e){this.x=t||0,this.y=e||0}add(t){const e=new c(0,0);return e.x=this.x+t.x,e.y=this.y+t.y,e}substract(t){const e=new c(0,0);return e.x=this.x-t.x,e.y=this.y-t.y,e}multiply(t){const e=new c(0,0);return e.x=this.x*t.x,e.y=this.y*t.y,e}multiplyByScaler(t){return this.multiply(new c(t,t))}division(t){const e=new c(0,0);return e.x=this.x/t.x,e.y=this.y/t.y,e}divisionByScalar(t){return this.division(new c(t,t))}getLength(){return Math.sqrt(this.x*this.x+this.y*this.y)}getDistanceWith(t){return Math.sqrt((this.x-t.x)*(this.x-t.x)+(this.y-t.y)*(this.y-t.y))}dot(t){return this.x*t.x+this.y*t.y}normalize(){const t=Math.pow(this.x*this.x+this.y*this.y,.5);this.x=this.x/t,this.y=this.y/t}isEqual(t){return this.x==t.x&&this.y==t.y}isNotEqual(t){return!this.isEqual(t)}}const m=class{static range(t,e,i){return ti&&(t=i),t}static sin(t){return Math.sin(t)}static cos(t){return Math.cos(t)}static abs(t){return Math.abs(t)}static sqrt(t){return Math.sqrt(t)}static cbrt(t){if(0===t)return t;let e=t;const i=e<0;let s;return i&&(e=-e),e===1/0?s=1/0:(s=Math.exp(Math.log(e)/3),s=(e/(s*s)+2*s)/3),i?-s:s}static getEasingSine(t){return t<0?0:t>1?1:.5-.5*this.cos(t*Math.PI)}static max(t,e){return t>e?t:e}static min(t,e){return t>e?e:t}static degreesToRadian(t){return t/180*Math.PI}static radianToDegrees(t){return 180*t/Math.PI}static directionToRadian(t,e){let i=Math.atan2(e.y,e.x)-Math.atan2(t.y,t.x);for(;i<-Math.PI;)i+=2*Math.PI;for(;i>Math.PI;)i-=2*Math.PI;return i}static directionToDegrees(t,e){const i=this.directionToRadian(t,e);let s=this.radianToDegrees(i);return e.x-t.x>0&&(s=-s),s}static radianToDirection(t){const e=new c;return e.x=this.sin(t),e.y=this.cos(t),e}static quadraticEquation(t,e,i){return this.abs(t)1&&(t=1),e<0?e=0:e>1&&(e=1),i<0?i=0:i>1&&(i=1),s<0?s=0:s>1&&(s=1),this._modelColor.R=t,this._modelColor.G=e,this._modelColor.B=i,this._modelColor.A=s}getModelColor(){return Object.assign({},this._modelColor)}setIsPremultipliedAlpha(t){this._isPremultipliedAlpha=t}isPremultipliedAlpha(){return this._isPremultipliedAlpha}setIsCulling(t){this._isCulling=t}isCulling(){return this._isCulling}setAnisotropy(t){this._anisortopy=t}getAnisotropy(){return this._anisortopy}getModel(){return this._model}constructor(){this._isCulling=!1,this._isPremultipliedAlpha=!1,this._anisortopy=0,this._modelColor=new y,this._mvpMatrix4x4=new p,this._mvpMatrix4x4.loadIdentity()}}var f=(t=>(t[t.CubismBlendMode_Normal=0]="CubismBlendMode_Normal",t[t.CubismBlendMode_Additive=1]="CubismBlendMode_Additive",t[t.CubismBlendMode_Multiplicative=2]="CubismBlendMode_Multiplicative",t))(f||{});class y{constructor(){this.R=1,this.G=1,this.B=1,this.A=1}}let x,v=!1,M=!1;const P={vertexOffset:0,vertexStep:2};class C{static startUp(t){if(v)return I("CubismFramework.startUp() is already done."),v;if(Live2DCubismCore._isStarted)return v=!0,!0;if(Live2DCubismCore._isStarted=!0,x=t,x&&Live2DCubismCore.Logging.csmSetLogFunction(x.logFunction),v=!0,v){const t=Live2DCubismCore.Version.csmGetVersion(),e=(16711680&t)>>16,i=65535&t,s=t;I("Live2D Cubism Core version: {0}.{1}.{2} ({3})",("00"+((4278190080&t)>>24)).slice(-2),("00"+e).slice(-2),("0000"+i).slice(-4),s)}return I("CubismFramework.startUp() is complete."),v}static cleanUp(){v=!1,M=!1,x=void 0}static initialize(){v?M?L("CubismFramework.initialize() skipped, already initialized."):(M=!0,I("CubismFramework.initialize() is complete.")):L("CubismFramework is not started.")}static dispose(){v?M?(_.staticRelease(),M=!1,I("CubismFramework.dispose() is complete.")):L("CubismFramework.dispose() skipped, not initialized."):L("CubismFramework is not started.")}static isStarted(){return v}static isInitialized(){return M}static coreLogFunction(t){Live2DCubismCore.Logging.csmGetLogFunction()&&Live2DCubismCore.Logging.csmGetLogFunction()(t)}static getLoggingLevel(){return null!=x?x.loggingLevel:S.LogLevel_Off}constructor(){}}var S=(t=>(t[t.LogLevel_Verbose=0]="LogLevel_Verbose",t[t.LogLevel_Debug=1]="LogLevel_Debug",t[t.LogLevel_Info=2]="LogLevel_Info",t[t.LogLevel_Warning=3]="LogLevel_Warning",t[t.LogLevel_Error=4]="LogLevel_Error",t[t.LogLevel_Off=5]="LogLevel_Off",t))(S||{});const b=()=>{};function w(t,...e){E.print(S.LogLevel_Debug,"[CSM][D]"+t+"\n",e)}function I(t,...e){E.print(S.LogLevel_Info,"[CSM][I]"+t+"\n",e)}function L(t,...e){E.print(S.LogLevel_Warning,"[CSM][W]"+t+"\n",e)}function T(t,...e){E.print(S.LogLevel_Error,"[CSM][E]"+t+"\n",e)}class E{static print(t,e,i){if(ti[e])))}static dumpBytes(t,e,i){for(let s=0;s0?this.print(t,"\n"):s%8==0&&s>0&&this.print(t," "),this.print(t,"{0} ",[255&e[s]]);this.print(t,"\n")}constructor(){}}class D{update(){this._model.update(),this._model.drawables.resetDynamicFlags()}getCanvasWidth(){return null==this._model?0:this._model.canvasinfo.CanvasWidth/this._model.canvasinfo.PixelsPerUnit}getCanvasHeight(){return null==this._model?0:this._model.canvasinfo.CanvasHeight/this._model.canvasinfo.PixelsPerUnit}saveParameters(){const t=this._model.parameters.count,e=this._savedParameters.length;for(let i=0;ie&&(e=this._model.parameters.minimumValues[t]),this._parameterValues[t]=1==i?e:this._parameterValues[t]=this._parameterValues[t]*(1-i)+e*i)}setParameterValueById(t,e,i=1){const s=this.getParameterIndex(t);this.setParameterValueByIndex(s,e,i)}addParameterValueByIndex(t,e,i=1){this.setParameterValueByIndex(t,this.getParameterValueByIndex(t)+e*i)}addParameterValueById(t,e,i=1){const s=this.getParameterIndex(t);this.addParameterValueByIndex(s,e,i)}multiplyParameterValueById(t,e,i=1){const s=this.getParameterIndex(t);this.multiplyParameterValueByIndex(s,e,i)}multiplyParameterValueByIndex(t,e,i=1){this.setParameterValueByIndex(t,this.getParameterValueByIndex(t)*(1+(e-1)*i))}getDrawableIds(){return this._drawableIds.slice()}getDrawableIndex(t){const e=this._model.drawables.count;for(let i=0;ie&&(t=e);for(let i=0;i0&&e.getEndTime()(t[t.ExpressionBlendType_Add=0]="ExpressionBlendType_Add",t[t.ExpressionBlendType_Multiply=1]="ExpressionBlendType_Multiply",t[t.ExpressionBlendType_Overwrite=2]="ExpressionBlendType_Overwrite",t))(U||{});t.CubismConfig=void 0,(k=t.CubismConfig||(t.CubismConfig={})).supportMoreMaskDivisions=!0,k.setOpacityFromMotion=!1;var N=(t=>(t[t.CubismMotionCurveTarget_Model=0]="CubismMotionCurveTarget_Model",t[t.CubismMotionCurveTarget_Parameter=1]="CubismMotionCurveTarget_Parameter",t[t.CubismMotionCurveTarget_PartOpacity=2]="CubismMotionCurveTarget_PartOpacity",t))(N||{}),V=(t=>(t[t.CubismMotionSegmentType_Linear=0]="CubismMotionSegmentType_Linear",t[t.CubismMotionSegmentType_Bezier=1]="CubismMotionSegmentType_Bezier",t[t.CubismMotionSegmentType_Stepped=2]="CubismMotionSegmentType_Stepped",t[t.CubismMotionSegmentType_InverseStepped=3]="CubismMotionSegmentType_InverseStepped",t))(V||{});class j{constructor(t=0,e=0){this.time=t,this.value=e}}class G{constructor(){this.basePointIndex=0,this.segmentType=0}}class X{constructor(){this.id="",this.type=0,this.segmentCount=0,this.baseSegmentIndex=0,this.fadeInTime=0,this.fadeOutTime=0}}class z{constructor(){this.fireTime=0,this.value=""}}class W{constructor(){this.duration=0,this.loop=!1,this.curveCount=0,this.eventCount=0,this.fps=0,this.curves=[],this.segments=[],this.points=[],this.events=[]}}class H{constructor(t){this._json=t}release(){this._json=void 0}getMotionDuration(){return this._json.Meta.Duration}isMotionLoop(){return this._json.Meta.Loop||!1}getEvaluationOptionFlag(t){return Y.EvaluationOptionFlag_AreBeziersRistricted==t&&!!this._json.Meta.AreBeziersRestricted}getMotionCurveCount(){return this._json.Meta.CurveCount}getMotionFps(){return this._json.Meta.Fps}getMotionTotalSegmentCount(){return this._json.Meta.TotalSegmentCount}getMotionTotalPointCount(){return this._json.Meta.TotalPointCount}getMotionFadeInTime(){return this._json.Meta.FadeInTime}getMotionFadeOutTime(){return this._json.Meta.FadeOutTime}getMotionCurveTarget(t){return this._json.Curves[t].Target}getMotionCurveId(t){return this._json.Curves[t].Id}getMotionCurveFadeInTime(t){return this._json.Curves[t].FadeInTime}getMotionCurveFadeOutTime(t){return this._json.Curves[t].FadeOutTime}getMotionCurveSegmentCount(t){return this._json.Curves[t].Segments.length}getMotionCurveSegment(t,e){return this._json.Curves[t].Segments[e]}getEventCount(){return this._json.Meta.UserDataCount||0}getTotalEventValueSize(){return this._json.Meta.TotalUserDataSize}getEventTime(t){return this._json.UserData[t].Time}getEventValue(t){return this._json.UserData[t].Value}}var Y=(t=>(t[t.EvaluationOptionFlag_AreBeziersRistricted=0]="EvaluationOptionFlag_AreBeziersRistricted",t))(Y||{});function q(t,e,i){const s=new j;return s.time=t.time+(e.time-t.time)*i,s.value=t.value+(e.value-t.value)*i,s}function $(t,e){let i=(e-t[0].time)/(t[1].time-t[0].time);return i<0&&(i=0),t[0].value+(t[1].value-t[0].value)*i}function Z(t,e){let i=(e-t[0].time)/(t[3].time-t[0].time);i<0&&(i=0);const s=q(t[0],t[1],i),r=q(t[1],t[2],i),a=q(t[2],t[3],i),o=q(s,r,i),n=q(r,a,i);return q(o,n,i).value}function J(t,e){const i=e,s=t[0].time,r=t[3].time,a=t[1].time,o=t[2].time,n=r-3*o+3*a-s,l=3*o-6*a+3*s,h=3*a-3*s,u=s-i,d=g.cardanoAlgorithmForBezier(n,l,h,u),c=q(t[0],t[1],d),m=q(t[1],t[2],d),p=q(t[2],t[3],d),_=q(c,m,d),f=q(m,p,d);return q(_,f,d).value}function Q(t,e){return t[0].value}function K(t,e){return t[1].value}function tt(t,e,i){const s=t.curves[e];let r=-1;const a=s.baseSegmentIndex+s.segmentCount;let o=0;for(let l=s.baseSegmentIndex;li){r=l;break}if(-1==r)return t.points[o].value;const n=t.segments[r];return n.evaluate(t.points.slice(n.basePointIndex),i)}class et extends R{constructor(){super(),this._eyeBlinkParameterIds=[],this._lipSyncParameterIds=[],this._sourceFrameRate=30,this._loopDurationSeconds=-1,this._isLoop=!1,this._isLoopFadeIn=!0,this._lastWeight=0}static create(t,e){const i=new et;return i.parse(t),i._sourceFrameRate=i._motionData.fps,i._loopDurationSeconds=i._motionData.duration,i._onFinishedMotion=e,i}doUpdateParameters(e,i,s,r){null==this._modelCurveIdEyeBlink&&(this._modelCurveIdEyeBlink="EyeBlink"),null==this._modelCurveIdLipSync&&(this._modelCurveIdLipSync="LipSync");let a=i-r.getStartTime();a<0&&(a=0);let o=Number.MAX_VALUE,n=Number.MAX_VALUE;const l=64;let h=0,u=0;this._eyeBlinkParameterIds.length>l&&w("too many eye blink targets : {0}",this._eyeBlinkParameterIds.length),this._lipSyncParameterIds.length>l&&w("too many lip sync targets : {0}",this._lipSyncParameterIds.length);const d=this._fadeInSeconds<=0?1:g.getEasingSine((i-r.getFadeInStartTime())/this._fadeInSeconds),c=this._fadeOutSeconds<=0||r.getEndTime()<0?1:g.getEasingSine((r.getEndTime()-i)/this._fadeOutSeconds);let m,p,_,f=a;if(this._isLoop)for(;f>this._motionData.duration;)f-=this._motionData.duration;const y=this._motionData.curves;for(p=0;p>t&1)continue;const r=i+(n-i)*s;e.setParameterValueById(this._eyeBlinkParameterIds[t],r)}if(o!=Number.MAX_VALUE)for(let t=0;t>t&1)continue;const r=i+(o-i)*s;e.setParameterValueById(this._lipSyncParameterIds[t],r)}for(;p=this._motionData.duration&&(this._isLoop?(r.setStartTime(i),this._isLoopFadeIn&&r.setFadeInStartTime(i)):(this._onFinishedMotion&&this._onFinishedMotion(this),r.setIsFinished(!0))),this._lastWeight=s}setIsLoop(t){this._isLoop=t}isLoop(){return this._isLoop}setIsLoopFadeIn(t){this._isLoopFadeIn=t}isLoopFadeIn(){return this._isLoopFadeIn}getDuration(){return this._isLoop?-1:this._loopDurationSeconds}getLoopDuration(){return this._loopDurationSeconds}setParameterFadeInTime(t,e){const i=this._motionData.curves;for(let s=0;snew X)),this._motionData.segments=Array.from({length:e.getMotionTotalSegmentCount()}).map((()=>new G)),this._motionData.events=Array.from({length:this._motionData.eventCount}).map((()=>new z)),this._motionData.points=[];let a=0,o=0;for(let n=0;nt&&this._motionData.events[i].fireTime<=e&&this._firedEventValues.push(this._motionData.events[i].value);return this._firedEventValues}}class it{constructor(){this._autoDelete=!1,this._available=!0,this._finished=!1,this._started=!1,this._startTimeSeconds=-1,this._fadeInStartTimeSeconds=0,this._endTimeSeconds=-1,this._stateTimeSeconds=0,this._stateWeight=0,this._lastEventCheckSeconds=0,this._motionQueueEntryHandle=this,this._fadeOutSeconds=0,this._isTriggeredFadeOut=!1}release(){this._autoDelete&&this._motion&&this._motion.release()}setFadeOut(t){this._fadeOutSeconds=t,this._isTriggeredFadeOut=!0}startFadeOut(t,e){const i=e+t;this._isTriggeredFadeOut=!0,(this._endTimeSeconds<0||inull!=e&&e._motionQueueEntryHandle==t))}setEventCallback(t,e=null){this._eventCallBack=t,this._eventCustomData=e}doUpdateMotion(t,e){let i=!1,s=0;for(;s(t[t.CubismPhysicsTargetType_Parameter=0]="CubismPhysicsTargetType_Parameter",t))(at||{}),ot=(t=>(t[t.CubismPhysicsSource_X=0]="CubismPhysicsSource_X",t[t.CubismPhysicsSource_Y=1]="CubismPhysicsSource_Y",t[t.CubismPhysicsSource_Angle=2]="CubismPhysicsSource_Angle",t))(ot||{});class nt{constructor(){this.initialPosition=new c(0,0),this.position=new c(0,0),this.lastPosition=new c(0,0),this.lastGravity=new c(0,0),this.force=new c(0,0),this.velocity=new c(0,0)}}class lt{constructor(){this.normalizationPosition={},this.normalizationAngle={}}}class ht{constructor(){this.source={}}}class ut{constructor(){this.destination={},this.translationScale=new c(0,0)}}class dt{constructor(){this.settings=[],this.inputs=[],this.outputs=[],this.particles=[],this.gravity=new c(0,0),this.wind=new c(0,0)}}class ct{constructor(t){this._json=t}release(){this._json=void 0}getGravity(){const t=new c(0,0);return t.x=this._json.Meta.EffectiveForces.Gravity.X,t.y=this._json.Meta.EffectiveForces.Gravity.Y,t}getWind(){const t=new c(0,0);return t.x=this._json.Meta.EffectiveForces.Wind.X,t.y=this._json.Meta.EffectiveForces.Wind.Y,t}getSubRigCount(){return this._json.Meta.PhysicsSettingCount}getTotalInputCount(){return this._json.Meta.TotalInputCount}getTotalOutputCount(){return this._json.Meta.TotalOutputCount}getVertexCount(){return this._json.Meta.VertexCount}getNormalizationPositionMinimumValue(t){return this._json.PhysicsSettings[t].Normalization.Position.Minimum}getNormalizationPositionMaximumValue(t){return this._json.PhysicsSettings[t].Normalization.Position.Maximum}getNormalizationPositionDefaultValue(t){return this._json.PhysicsSettings[t].Normalization.Position.Default}getNormalizationAngleMinimumValue(t){return this._json.PhysicsSettings[t].Normalization.Angle.Minimum}getNormalizationAngleMaximumValue(t){return this._json.PhysicsSettings[t].Normalization.Angle.Maximum}getNormalizationAngleDefaultValue(t){return this._json.PhysicsSettings[t].Normalization.Angle.Default}getInputCount(t){return this._json.PhysicsSettings[t].Input.length}getInputWeight(t,e){return this._json.PhysicsSettings[t].Input[e].Weight}getInputReflect(t,e){return this._json.PhysicsSettings[t].Input[e].Reflect}getInputType(t,e){return this._json.PhysicsSettings[t].Input[e].Type}getInputSourceId(t,e){return this._json.PhysicsSettings[t].Input[e].Source.Id}getOutputCount(t){return this._json.PhysicsSettings[t].Output.length}getOutputVertexIndex(t,e){return this._json.PhysicsSettings[t].Output[e].VertexIndex}getOutputAngleScale(t,e){return this._json.PhysicsSettings[t].Output[e].Scale}getOutputWeight(t,e){return this._json.PhysicsSettings[t].Output[e].Weight}getOutputDestinationId(t,e){return this._json.PhysicsSettings[t].Output[e].Destination.Id}getOutputType(t,e){return this._json.PhysicsSettings[t].Output[e].Type}getOutputReflect(t,e){return this._json.PhysicsSettings[t].Output[e].Reflect}getParticleCount(t){return this._json.PhysicsSettings[t].Vertices.length}getParticleMobility(t,e){return this._json.PhysicsSettings[t].Vertices[e].Mobility}getParticleDelay(t,e){return this._json.PhysicsSettings[t].Vertices[e].Delay}getParticleAcceleration(t,e){return this._json.PhysicsSettings[t].Vertices[e].Acceleration}getParticleRadius(t,e){return this._json.PhysicsSettings[t].Vertices[e].Radius}getParticlePosition(t,e){const i=new c(0,0);return i.x=this._json.PhysicsSettings[t].Vertices[e].Position.X,i.y=this._json.PhysicsSettings[t].Vertices[e].Position.Y,i}}const mt="Angle";class gt{static create(t){const e=new gt;return e.parse(t),e._physicsRig.gravity.y=0,e}evaluate(t,e){let i,s,r,a;const o=new c;let n,l,h,u,d,m,p,_;d=t.getModel().parameters.values,m=t.getModel().parameters.maximumValues,p=t.getModel().parameters.minimumValues,_=t.getModel().parameters.defaultValues;for(let f=0;f=n.particleCount)break;-1==h[e].destinationParameterIndex&&(h[e].destinationParameterIndex=t.getParameterIndex(h[e].destination.id));const s=new c;s.x=u[i].position.x-u[i-1].position.x,s.y=u[i].position.y-u[i-1].position.y,a=h[e].getValue(s,u,i,h[e].reflect,this._options.gravity);const r=h[e].destinationParameterIndex,o=!Float32Array.prototype.slice&&"subarray"in Float32Array.prototype?JSON.parse(JSON.stringify(d.subarray(r))):d.slice(r);It(o,p[r],m[r],a,h[e]);for(let t=r,e=0;t=2?e[i-1].position.substract(e[i-2].position):r.multiplyByScaler(-1),a=g.directionToRadian(r,t),s&&(a*=-1),a}function Pt(t,e){return Math.min(t,e)+function(t,e){return Math.abs(Math.max(t,e)-Math.min(t,e))}(t,e)/2}function Ct(t,e){return t.x}function St(t,e){return t.y}function bt(t,e){return e}function wt(t,e,i,s,r,a,o,n){let l,h,u,d,m=new c(0,0),p=new c(0,0),_=new c(0,0),f=new c(0,0);t[0].position=new c(i.x,i.y),l=g.degreesToRadian(s),d=g.radianToDirection(l),d.normalize();for(let y=1;yi&&(o>r.valueExceededMaximum&&(r.valueExceededMaximum=o),o=i),n=r.weight/100,n>=1||(o=t[0]*(1-n)+o*n),t[0]=o}function Lt(t,e,i,s,r,a,o,n){let l=0;const h=g.max(i,e);ht&&(t=u);const d=g.min(r,a),c=g.max(r,a),m=o,p=Pt(u,h),_=t-p;switch(Math.sign(_)){case 1:{const t=c-m,e=h-p;0!=e&&(l=_*(t/e),l+=m);break}case-1:{const t=d-m,e=u-p;0!=e&&(l=_*(t/e),l+=m);break}case 0:l=m}return n?l:-1*l}class Tt{constructor(t=0,e=0,i=0,s=0){this.x=t,this.y=e,this.width=i,this.height=s}getCenterX(){return this.x+.5*this.width}getCenterY(){return this.y+.5*this.height}getRight(){return this.x+this.width}getBottom(){return this.y+this.height}setRect(t){this.x=t.x,this.y=t.y,this.width=t.width,this.height=t.height}expand(t,e){this.x-=t,this.y-=e,this.width+=2*t,this.height+=2*e}}let Et,Dt,Ft;class At{getChannelFlagAsColor(t){return this._channelColors[t]}getMaskRenderTexture(){let t=0;if(this._maskTexture&&0!=this._maskTexture.texture&&(this._maskTexture.frameNo=this._currentFrameNo,t=this._maskTexture.texture),0==t){const e=this._clippingMaskBufferSize;this._colorBuffer=this.gl.createTexture(),this.gl.bindTexture(this.gl.TEXTURE_2D,this._colorBuffer),this.gl.texImage2D(this.gl.TEXTURE_2D,0,this.gl.RGBA,e,e,0,this.gl.RGBA,this.gl.UNSIGNED_BYTE,null),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_S,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_T,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MIN_FILTER,this.gl.LINEAR),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MAG_FILTER,this.gl.LINEAR),this.gl.bindTexture(this.gl.TEXTURE_2D,null),t=this.gl.createFramebuffer(),this.gl.bindFramebuffer(this.gl.FRAMEBUFFER,t),this.gl.framebufferTexture2D(this.gl.FRAMEBUFFER,this.gl.COLOR_ATTACHMENT0,this.gl.TEXTURE_2D,this._colorBuffer,0),this.gl.bindFramebuffer(this.gl.FRAMEBUFFER,Ft),this._maskTexture=new Bt(this._currentFrameNo,t)}return t}setGL(t){this.gl=t}calcClippedDrawTotalBounds(t,e){let i=Number.MAX_VALUE,s=Number.MAX_VALUE,r=Number.MIN_VALUE,a=Number.MIN_VALUE;const o=e._clippedDrawableIndexList.length;for(let n=0;nc&&(c=e),im&&(m=i)}if(u!=Number.MAX_VALUE)if(ur&&(r=c),m>a&&(a=m),i==Number.MAX_VALUE)e._allClippedDrawRect.x=0,e._allClippedDrawRect.y=0,e._allClippedDrawRect.width=0,e._allClippedDrawRect.height=0,e._isUsing=!1;else{e._isUsing=!0;const t=r-i,o=a-s;e._allClippedDrawRect.x=i,e._allClippedDrawRect.y=s,e._allClippedDrawRect.width=t,e._allClippedDrawRect.height=o}}}constructor(){this._maskRenderTexture=null,this._colorBuffer=null,this._currentFrameNo=0,this._clippingMaskBufferSize=256,this._clippingContextListForMask=[],this._clippingContextListForDraw=[],this._channelColors=[],this._tmpBoundsOnModel=new Tt,this._tmpMatrix=new p,this._tmpMatrixForMask=new p,this._tmpMatrixForDraw=new p;let t=new y;t.R=1,t.G=0,t.B=0,t.A=0,this._channelColors.push(t),t=new y,t.R=0,t.G=1,t.B=0,t.A=0,this._channelColors.push(t),t=new y,t.R=0,t.G=0,t.B=1,t.A=0,this._channelColors.push(t),t=new y,t.R=0,t.G=0,t.B=0,t.A=1,this._channelColors.push(t)}release(){var t,e,i;const s=this;for(let r=0;r0){this.gl.viewport(0,0,this._clippingMaskBufferSize,this._clippingMaskBufferSize),this._maskRenderTexture=this.getMaskRenderTexture(),e.getMvpMatrix(),e.preDraw(),this.setupLayoutBounds(i),this.gl.bindFramebuffer(this.gl.FRAMEBUFFER,this._maskRenderTexture),this.gl.clearColor(1,1,1,1),this.gl.clear(this.gl.COLOR_BUFFER_BIT);for(let i=0;i(t[t.ShaderNames_SetupMask=0]="ShaderNames_SetupMask",t[t.ShaderNames_NormalPremultipliedAlpha=1]="ShaderNames_NormalPremultipliedAlpha",t[t.ShaderNames_NormalMaskedPremultipliedAlpha=2]="ShaderNames_NormalMaskedPremultipliedAlpha",t[t.ShaderNames_NomralMaskedInvertedPremultipliedAlpha=3]="ShaderNames_NomralMaskedInvertedPremultipliedAlpha",t[t.ShaderNames_AddPremultipliedAlpha=4]="ShaderNames_AddPremultipliedAlpha",t[t.ShaderNames_AddMaskedPremultipliedAlpha=5]="ShaderNames_AddMaskedPremultipliedAlpha",t[t.ShaderNames_AddMaskedPremultipliedAlphaInverted=6]="ShaderNames_AddMaskedPremultipliedAlphaInverted",t[t.ShaderNames_MultPremultipliedAlpha=7]="ShaderNames_MultPremultipliedAlpha",t[t.ShaderNames_MultMaskedPremultipliedAlpha=8]="ShaderNames_MultMaskedPremultipliedAlpha",t[t.ShaderNames_MultMaskedPremultipliedAlphaInverted=9]="ShaderNames_MultMaskedPremultipliedAlphaInverted",t))(kt||{});const Ut="attribute vec4 a_position;attribute vec2 a_texCoord;varying vec2 v_texCoord;varying vec4 v_myPos;uniform mat4 u_clipMatrix;void main(){ gl_Position = u_clipMatrix * a_position; v_myPos = u_clipMatrix * a_position; v_texCoord = a_texCoord; v_texCoord.y = 1.0 - v_texCoord.y;}",Nt="precision mediump float;varying vec2 v_texCoord;varying vec4 v_myPos;uniform vec4 u_baseColor;uniform vec4 u_channelFlag;uniform sampler2D s_texture0;void main(){ float isInside = step(u_baseColor.x, v_myPos.x/v_myPos.w) * step(u_baseColor.y, v_myPos.y/v_myPos.w) * step(v_myPos.x/v_myPos.w, u_baseColor.z) * step(v_myPos.y/v_myPos.w, u_baseColor.w); gl_FragColor = u_channelFlag * texture2D(s_texture0, v_texCoord).a * isInside;}",Vt="attribute vec4 a_position;attribute vec2 a_texCoord;varying vec2 v_texCoord;uniform mat4 u_matrix;void main(){ gl_Position = u_matrix * a_position; v_texCoord = a_texCoord; v_texCoord.y = 1.0 - v_texCoord.y;}",jt="attribute vec4 a_position;attribute vec2 a_texCoord;varying vec2 v_texCoord;varying vec4 v_clipPos;uniform mat4 u_matrix;uniform mat4 u_clipMatrix;void main(){ gl_Position = u_matrix * a_position; v_clipPos = u_clipMatrix * a_position; v_texCoord = a_texCoord; v_texCoord.y = 1.0 - v_texCoord.y;}",Gt="precision mediump float;varying vec2 v_texCoord;uniform vec4 u_baseColor;uniform sampler2D s_texture0;void main(){ gl_FragColor = texture2D(s_texture0 , v_texCoord) * u_baseColor;}",Xt="precision mediump float;varying vec2 v_texCoord;varying vec4 v_clipPos;uniform vec4 u_baseColor;uniform vec4 u_channelFlag;uniform sampler2D s_texture0;uniform sampler2D s_texture1;void main(){ vec4 col_formask = texture2D(s_texture0 , v_texCoord) * u_baseColor; vec4 clipMask = (1.0 - texture2D(s_texture1, v_clipPos.xy / v_clipPos.w)) * u_channelFlag; float maskVal = clipMask.r + clipMask.g + clipMask.b + clipMask.a; col_formask = col_formask * maskVal; gl_FragColor = col_formask;}",zt="precision mediump float;varying vec2 v_texCoord;varying vec4 v_clipPos;uniform sampler2D s_texture0;uniform sampler2D s_texture1;uniform vec4 u_channelFlag;uniform vec4 u_baseColor;void main(){vec4 col_formask = texture2D(s_texture0, v_texCoord) * u_baseColor;vec4 clipMask = (1.0 - texture2D(s_texture1, v_clipPos.xy / v_clipPos.w)) * u_channelFlag;float maskVal = clipMask.r + clipMask.g + clipMask.b + clipMask.a;col_formask = col_formask * (1.0 - maskVal);gl_FragColor = col_formask;}";class Wt extends _{constructor(){super(),this._clippingContextBufferForMask=null,this._clippingContextBufferForDraw=null,this._clippingManager=new At,this.firstDraw=!0,this._textures={},this._sortedDrawableIndexList=[],this._bufferData={vertex:null,uv:null,index:null}}initialize(t){t.isUsingMasking()&&(this._clippingManager=new At,this._clippingManager.initialize(t,t.getDrawableCount(),t.getDrawableMasks(),t.getDrawableMaskCounts()));for(let e=t.getDrawableCount()-1;e>=0;e--)this._sortedDrawableIndexList[e]=0;super.initialize(t)}bindTexture(t,e){this._textures[t]=e}getBindedTextures(){return this._textures}setClippingMaskBufferSize(t){this._clippingManager.release(),this._clippingManager=new At,this._clippingManager.setClippingMaskBufferSize(t),this._clippingManager.initialize(this.getModel(),this.getModel().getDrawableCount(),this.getModel().getDrawableMasks(),this.getModel().getDrawableMaskCounts())}getClippingMaskBufferSize(){return this._clippingManager.getClippingMaskBufferSize()}release(){var t,e,i;const s=this;this._clippingManager.release(),s._clippingManager=void 0,null==(t=this.gl)||t.deleteBuffer(this._bufferData.vertex),this._bufferData.vertex=null,null==(e=this.gl)||e.deleteBuffer(this._bufferData.uv),this._bufferData.uv=null,null==(i=this.gl)||i.deleteBuffer(this._bufferData.index),this._bufferData.index=null,s._bufferData=void 0,s._textures=void 0}doDrawModel(){this.preDraw(),null!=this._clippingManager&&this._clippingManager.setupClippingContext(this.getModel(),this);const t=this.getModel().getDrawableCount(),e=this.getModel().getDrawableRenderOrders();for(let i=0;i{Wt.doStaticRelease()};class Ht{constructor(t){this.groups=t.Groups,this.hitAreas=t.HitAreas,this.layout=t.Layout,this.moc=t.FileReferences.Moc,this.expressions=t.FileReferences.Expressions,this.motions=t.FileReferences.Motions,this.textures=t.FileReferences.Textures,this.physics=t.FileReferences.Physics,this.pose=t.FileReferences.Pose}getEyeBlinkParameters(){var t,e;return null==(e=null==(t=this.groups)?void 0:t.find((t=>"EyeBlink"===t.Name)))?void 0:e.Ids}getLipSyncParameters(){var t,e;return null==(e=null==(t=this.groups)?void 0:t.find((t=>"LipSync"===t.Name)))?void 0:e.Ids}}const Yt="ParamAngleX",qt="ParamAngleY",$t="ParamAngleZ",Zt="ParamEyeBallX",Jt="ParamEyeBallY",Qt="ParamBodyAngleX",Kt="ParamBreath";var te;t.config=void 0,(te=t.config||(t.config={})).LOG_LEVEL_VERBOSE=0,te.LOG_LEVEL_WARNING=1,te.LOG_LEVEL_ERROR=2,te.LOG_LEVEL_NONE=999,te.logLevel=te.LOG_LEVEL_WARNING,te.sound=!0,te.motionSync=!0,te.motionFadingDuration=500,te.idleMotionFadingDuration=2e3,te.expressionFadingDuration=500,te.preserveExpressionOnMotion=!0,te.cubism4=t.CubismConfig;const ee={log(e,...i){t.config.logLevel<=t.config.LOG_LEVEL_VERBOSE&&console.log(`[${e}]`,...i)},warn(e,...i){t.config.logLevel<=t.config.LOG_LEVEL_WARNING&&console.warn(`[${e}]`,...i)},error(e,...i){t.config.logLevel<=t.config.LOG_LEVEL_ERROR&&console.error(`[${e}]`,...i)}};function ie(t,e,i){return ti?i:t}function se(t,e){e.forEach((e=>{Object.getOwnPropertyNames(e.prototype).forEach((i=>{"constructor"!==i&&Object.defineProperty(t.prototype,i,Object.getOwnPropertyDescriptor(e.prototype,i))}))}))}function re(t){let e=t.lastIndexOf("/");return-1!=e&&(t=t.slice(0,e)),e=t.lastIndexOf("/"),-1!==e&&(t=t.slice(e+1)),t}function ae(t,e){const i=t.indexOf(e);-1!==i&&t.splice(i,1)}class oe extends e.EventEmitter{constructor(t,e){super(),this.expressions=[],this.reserveExpressionIndex=-1,this.destroyed=!1,this.settings=t,this.tag=`ExpressionManager(${t.name})`}init(){this.defaultExpression=this.createExpression({},void 0),this.currentExpression=this.defaultExpression,this.stopAllExpressions()}loadExpression(t){return __async(this,null,(function*(){if(!this.definitions[t])return void ee.warn(this.tag,`Undefined expression at [${t}]`);if(null===this.expressions[t])return void ee.warn(this.tag,`Cannot set expression at [${t}] because it's already failed in loading.`);if(this.expressions[t])return this.expressions[t];const e=yield this._loadExpression(t);return this.expressions[t]=e,e}))}_loadExpression(t){throw new Error("Not implemented.")}setRandomExpression(){return __async(this,null,(function*(){if(this.definitions.length){const t=[];for(let e=0;e-1&&tl&&(a*=l/n,o*=l/n),this.vx+=a,this.vy+=o;const h=Math.sqrt(__pow(this.vx,2)+__pow(this.vy,2)),u=.5*(Math.sqrt(__pow(l,2)+8*l*s)-l);h>u&&(this.vx*=u/h,this.vy*=u/h),this.x+=this.vx,this.y+=this.vy}}class le{constructor(t){this.json=t;let e=t.url;if("string"!=typeof e)throw new TypeError("The `url` field in settings JSON must be defined as a string.");this.url=e,this.name=re(this.url)}resolveURL(t){return e.url.resolve(this.url,t)}replaceFiles(t){this.moc=t(this.moc,"moc"),void 0!==this.pose&&(this.pose=t(this.pose,"pose")),void 0!==this.physics&&(this.physics=t(this.physics,"physics"));for(let e=0;e(t.push(e),e))),t}validateFiles(t){const e=(e,i)=>{const s=this.resolveURL(e);if(!t.includes(s)){if(i)throw new Error(`File "${e}" is defined in settings, but doesn't exist in given files`);return!1}return!0};[this.moc,...this.textures].forEach((t=>e(t,!0)));return this.getDefinedFiles().filter((t=>e(t,!1)))}}var he=(t=>(t[t.NONE=0]="NONE",t[t.IDLE=1]="IDLE",t[t.NORMAL=2]="NORMAL",t[t.FORCE=3]="FORCE",t))(he||{});class ue{constructor(){this.debug=!1,this.currentPriority=0,this.reservePriority=0}reserve(t,e,i){if(i<=0)return ee.log(this.tag,"Cannot start a motion with MotionPriority.NONE."),!1;if(t===this.currentGroup&&e===this.currentIndex)return ee.log(this.tag,"Motion is already playing.",this.dump(t,e)),!1;if(t===this.reservedGroup&&e===this.reservedIndex||t===this.reservedIdleGroup&&e===this.reservedIdleIndex)return ee.log(this.tag,"Motion is already reserved.",this.dump(t,e)),!1;if(1===i){if(0!==this.currentPriority)return ee.log(this.tag,"Cannot start idle motion because another motion is playing.",this.dump(t,e)),!1;if(void 0!==this.reservedIdleGroup)return ee.log(this.tag,"Cannot start idle motion because another idle motion has reserved.",this.dump(t,e)),!1;this.setReservedIdle(t,e)}else{if(i<3){if(i<=this.currentPriority)return ee.log(this.tag,"Cannot start motion because another motion is playing as an equivalent or higher priority.",this.dump(t,e)),!1;if(i<=this.reservePriority)return ee.log(this.tag,"Cannot start motion because another motion has reserved as an equivalent or higher priority.",this.dump(t,e)),!1}this.setReserved(t,e,i)}return!0}start(t,e,i,s){if(1===s){if(this.setReservedIdle(void 0,void 0),0!==this.currentPriority)return ee.log(this.tag,"Cannot start idle motion because another motion is playing.",this.dump(e,i)),!1}else{if(e!==this.reservedGroup||i!==this.reservedIndex)return ee.log(this.tag,"Cannot start motion because another motion has taken the place.",this.dump(e,i)),!1;this.setReserved(void 0,void 0,0)}return!!t&&(this.setCurrent(e,i,s),!0)}complete(){this.setCurrent(void 0,void 0,0)}setCurrent(t,e,i){this.currentPriority=i,this.currentGroup=t,this.currentIndex=e}setReserved(t,e,i){this.reservePriority=i,this.reservedGroup=t,this.reservedIndex=e}setReservedIdle(t,e){this.reservedIdleGroup=t,this.reservedIdleIndex=e}isActive(t,e){return t===this.currentGroup&&e===this.currentIndex||t===this.reservedGroup&&e===this.reservedIndex||t===this.reservedIdleGroup&&e===this.reservedIdleIndex}reset(){this.setCurrent(void 0,void 0,0),this.setReserved(void 0,void 0,0),this.setReservedIdle(void 0,void 0)}shouldRequestIdleMotion(){return void 0===this.currentGroup&&void 0===this.reservedIdleGroup}shouldOverrideExpression(){return!t.config.preserveExpressionOnMotion&&this.currentPriority>1}dump(t,e){if(this.debug){return`\n group = "${t}", index = ${e}\n`+["currentPriority","reservePriority","currentGroup","currentIndex","reservedGroup","reservedIndex","reservedIdleGroup","reservedIdleIndex"].map((t=>"["+t+"] "+this[t])).join("\n")}return""}}class de{static get volume(){return this._volume}static set volume(t){this._volume=(t>1?1:t<0?0:t)||0,this.audios.forEach((t=>t.volume=this._volume))}static add(t,e,i){const s=new Audio(t);return s.volume=this._volume,s.preload="auto",s.addEventListener("ended",(()=>{this.dispose(s),null==e||e()})),s.addEventListener("error",(e=>{this.dispose(s),ee.warn("SoundManager",`Error occurred on "${t}"`,e.error),null==i||i(e.error)})),this.audios.push(s),s}static play(t){return new Promise(((e,i)=>{var s;null==(s=t.play())||s.catch((e=>{t.dispatchEvent(new ErrorEvent("error",{error:e})),i(e)})),t.readyState===t.HAVE_ENOUGH_DATA?e():t.addEventListener("canplaythrough",e)}))}static dispose(t){t.pause(),t.removeAttribute("src"),ae(this.audios,t)}static destroy(){for(let t=this.audios.length-1;t>=0;t--)this.dispose(this.audios[t])}}de.audios=[],de._volume=.5;var ce=(t=>(t.ALL="ALL",t.IDLE="IDLE",t.NONE="NONE",t))(ce||{});class me extends e.EventEmitter{constructor(t,e){super(),this.motionGroups={},this.state=new ue,this.playing=!1,this.destroyed=!1,this.settings=t,this.tag=`MotionManager(${t.name})`,this.state.tag=this.tag}init(t){(null==t?void 0:t.idleMotionGroup)&&(this.groups.idle=t.idleMotionGroup),this.setupMotions(t),this.stopAllMotions()}setupMotions(t){for(const i of Object.keys(this.definitions))this.motionGroups[i]=[];let e;switch(null==t?void 0:t.motionPreload){case"NONE":return;case"ALL":e=Object.keys(this.definitions);break;default:e=[this.groups.idle]}for(const i of e)if(this.definitions[i])for(let t=0;tthis.currentAudio=void 0),(()=>this.currentAudio=void 0)),this.currentAudio=o}catch(l){ee.warn(this.tag,"Failed to create audio",t,l)}}const n=yield this.loadMotion(e,i);if(o){const e=de.play(o).catch((t=>ee.warn(this.tag,"Failed to play audio",o.src,t)));t.config.motionSync&&(yield e)}return this.state.start(n,e,i,s)?(ee.log(this.tag,"Start motion:",this.getMotionName(a)),this.emit("motionStart",e,i,o),this.state.shouldOverrideExpression()&&this.expressionManager&&this.expressionManager.resetExpression(),this.playing=!0,this._startMotion(n),!0):(o&&(de.dispose(o),this.currentAudio=void 0),!1)}))}startRandomMotion(t,e){return __async(this,null,(function*(){const i=this.definitions[t];if(null==i?void 0:i.length){const s=[];for(let e=0;et.index>=0));for(const e of t)this.hitAreas[e.name]=e}hitTest(t,e){return Object.keys(this.hitAreas).filter((i=>this.isHit(i,t,e)))}isHit(t,e,i){if(!this.hitAreas[t])return!1;const s=this.hitAreas[t].index,r=this.getDrawableBounds(s,ge);return r.x<=e&&e<=r.x+r.width&&r.y<=i&&i<=r.y+r.height}getDrawableBounds(t,e){const i=this.getDrawableVertices(t);let s=i[0],r=i[0],a=i[1],o=i[1];for(let n=0;n{200!==a.status&&0!==a.status||!a.response?a.onerror():s(a.response)},a.onerror=()=>{ee.warn("XHRLoader",`Failed to load resource as ${a.responseType} (Status ${a.status}): ${e}`),r(new _e("Network error.",e,a.status))},a.onabort=()=>r(new _e("Aborted.",e,a.status,!0)),a.onloadend=()=>{var e;fe.allXhrSet.delete(a),t&&(null==(e=fe.xhrMap.get(t))||e.delete(a))},a}static cancelXHRs(){var t;null==(t=fe.xhrMap.get(this))||t.forEach((t=>{t.abort(),fe.allXhrSet.delete(t)})),fe.xhrMap.delete(this)}static release(){fe.allXhrSet.forEach((t=>t.abort())),fe.allXhrSet.clear(),fe.xhrMap=new WeakMap}};let ye=fe;function xe(t,e){let i=-1;return function s(r,a){if(a)return Promise.reject(a);if(r<=i)return Promise.reject(new Error("next() called multiple times"));i=r;const o=t[r];if(!o)return Promise.resolve();try{return Promise.resolve(o(e,s.bind(null,r+1)))}catch(n){return Promise.reject(n)}}(0)}ye.xhrMap=new WeakMap,ye.allXhrSet=new Set,ye.loader=(t,e)=>new Promise(((e,i)=>{fe.createXHR(t.target,t.settings?t.settings.resolveURL(t.url):t.url,t.type,(i=>{t.result=i,e()}),i).send()}));class ve{static load(t){return xe(this.middlewares,t).then((()=>t.result))}}ve.middlewares=[ye.loader];const Me="Live2DFactory",Pe=(t,e)=>__async(this,null,(function*(){if("string"==typeof t.source){const e=yield ve.load({url:t.source,type:"json",target:t.live2dModel});e.url=t.source,t.source=e,t.live2dModel.emit("settingsJSONLoaded",e)}return e()})),Ce=(t,e)=>__async(this,null,(function*(){if(t.source instanceof le)return t.settings=t.source,e();if("object"==typeof t.source){const i=Te.findRuntime(t.source);if(i){const s=i.createModelSettings(t.source);return t.settings=s,t.live2dModel.emit("settingsLoaded",s),e()}}throw new TypeError("Unknown settings format.")})),Se=(t,e)=>{if(t.settings){const i=Te.findRuntime(t.settings);if(i)return i.ready().then(e)}return e()},be=(t,e)=>__async(this,null,(function*(){yield e();const i=t.internalModel;if(i){const e=t.settings,s=Te.findRuntime(e);if(s){const r=[];e.pose&&r.push(ve.load({settings:e,url:e.pose,type:"json",target:i}).then((e=>{i.pose=s.createPose(i.coreModel,e),t.live2dModel.emit("poseLoaded",i.pose)})).catch((e=>{t.live2dModel.emit("poseLoadError",e),ee.warn(Me,"Failed to load pose.",e)}))),e.physics&&r.push(ve.load({settings:e,url:e.physics,type:"json",target:i}).then((e=>{i.physics=s.createPhysics(i.coreModel,e),t.live2dModel.emit("physicsLoaded",i.physics)})).catch((e=>{t.live2dModel.emit("physicsLoadError",e),ee.warn(Me,"Failed to load physics.",e)}))),r.length&&(yield Promise.all(r))}}})),we=(t,e)=>__async(this,null,(function*(){if(!t.settings)throw new TypeError("Missing settings.");{const i=t.live2dModel,r=t.settings.textures.map((e=>function(t,e={}){const i={resourceOptions:{crossorigin:e.crossOrigin}};if(s.Texture.fromURL)return s.Texture.fromURL(t,i).catch((t=>{if(t instanceof Error)throw t;const e=new Error("Texture loading error");throw e.event=t,e}));i.resourceOptions.autoLoad=!1;const r=s.Texture.from(t,i);if(r.baseTexture.valid)return Promise.resolve(r);const a=r.baseTexture.resource;return null!=a._live2d_load||(a._live2d_load=new Promise(((t,e)=>{const i=t=>{a.source.removeEventListener("error",i);const s=new Error("Texture loading error");s.event=t,e(s)};a.source.addEventListener("error",i),a.load().then((()=>t(r))).catch(i)}))),a._live2d_load}(t.settings.resolveURL(e),{crossOrigin:t.options.crossOrigin})));if(yield e(),!t.internalModel)throw new TypeError("Missing internal model.");i.internalModel=t.internalModel,i.emit("modelLoaded",t.internalModel),i.textures=yield Promise.all(r),i.emit("textureLoaded",i.textures)}})),Ie=(t,e)=>__async(this,null,(function*(){const i=t.settings;if(i instanceof le){const s=Te.findRuntime(i);if(!s)throw new TypeError("Unknown model settings.");const r=yield ve.load({settings:i,url:i.moc,type:"arraybuffer",target:t.live2dModel});if(!s.isValidMoc(r))throw new Error("Invalid moc data");const a=s.createCoreModel(r);return t.internalModel=s.createInternalModel(a,i,t.options),e()}throw new TypeError("Missing settings.")})),Le=class{static registerRuntime(t){Le.runtimes.push(t),Le.runtimes.sort(((t,e)=>e.version-t.version))}static findRuntime(t){for(const e of Le.runtimes)if(e.test(t))return e}static setupLive2DModel(t,e,i){return __async(this,null,(function*(){const s=new Promise((e=>t.once("textureLoaded",e))),r=new Promise((e=>t.once("modelLoaded",e))),a=Promise.all([s,r]).then((()=>t.emit("ready")));yield xe(Le.live2DModelMiddlewares,{live2dModel:t,source:e,options:i||{}}),yield a,t.emit("load")}))}static loadMotion(t,e,i){var s;const r=s=>t.emit("motionLoadError",e,i,s);try{const a=null==(s=t.definitions[e])?void 0:s[i];if(!a)return Promise.resolve(void 0);t.listeners("destroy").includes(Le.releaseTasks)||t.once("destroy",Le.releaseTasks);let o=Le.motionTasksMap.get(t);o||(o={},Le.motionTasksMap.set(t,o));let n=o[e];n||(n=[],o[e]=n);const l=t.getMotionFile(a);return null!=n[i]||(n[i]=ve.load({url:l,settings:t.settings,type:t.motionDataType,target:t}).then((s=>{var r;const o=null==(r=Le.motionTasksMap.get(t))?void 0:r[e];o&&delete o[i];const n=t.createMotion(s,e,a);return t.emit("motionLoaded",e,i,n),n})).catch((e=>{ee.warn(t.tag,`Failed to load motion: ${l}\n`,e),r(e)}))),n[i]}catch(a){ee.warn(t.tag,`Failed to load motion at "${e}"[${i}]\n`,a),r(a)}return Promise.resolve(void 0)}static loadExpression(t,e){const i=i=>t.emit("expressionLoadError",e,i);try{const s=t.definitions[e];if(!s)return Promise.resolve(void 0);t.listeners("destroy").includes(Le.releaseTasks)||t.once("destroy",Le.releaseTasks);let r=Le.expressionTasksMap.get(t);r||(r=[],Le.expressionTasksMap.set(t,r));const a=t.getExpressionFile(s);return null!=r[e]||(r[e]=ve.load({url:a,settings:t.settings,type:"json",target:t}).then((i=>{const r=Le.expressionTasksMap.get(t);r&&delete r[e];const a=t.createExpression(i,s);return t.emit("expressionLoaded",e,a),a})).catch((e=>{ee.warn(t.tag,`Failed to load expression: ${a}\n`,e),i(e)}))),r[e]}catch(s){ee.warn(t.tag,`Failed to load expression at [${e}]\n`,s),i(s)}return Promise.resolve(void 0)}static releaseTasks(){this instanceof me?Le.motionTasksMap.delete(this):Le.expressionTasksMap.delete(this)}};let Te=Le;Te.runtimes=[],Te.urlToJSON=Pe,Te.jsonToSettings=Ce,Te.waitUntilReady=Se,Te.setupOptionals=be,Te.setupEssentials=we,Te.createInternalModel=Ie,Te.live2DModelMiddlewares=[Pe,Ce,Se,be,we,Ie],Te.motionTasksMap=new WeakMap,Te.expressionTasksMap=new WeakMap,me.prototype._loadMotion=function(t,e){return Te.loadMotion(this,t,e)},oe.prototype._loadExpression=function(t){return Te.loadExpression(this,t)};class Ee{constructor(){this._autoInteract=!1}get autoInteract(){return this._autoInteract}set autoInteract(t){t!==this._autoInteract&&(t?this.on("pointertap",De,this):this.off("pointertap",De,this),this._autoInteract=t)}registerInteraction(t){t!==this.interactionManager&&(this.unregisterInteraction(),this._autoInteract&&t&&(this.interactionManager=t,t.on("pointermove",Fe,this)))}unregisterInteraction(){var t;this.interactionManager&&(null==(t=this.interactionManager)||t.off("pointermove",Fe,this),this.interactionManager=void 0)}}function De(t){this.tap(t.data.global.x,t.data.global.y)}function Fe(t){this.focus(t.data.global.x,t.data.global.y)}class Ae extends i.Transform{}const Be=new i.Point,Re=new i.Matrix;let Oe;class ke extends r.Container{constructor(t){super(),this.tag="Live2DModel(uninitialized)",this.textures=[],this.transform=new Ae,this.anchor=new i.ObservablePoint(this.onAnchorChange,this,0,0),this.glContextID=-1,this.elapsedTime=performance.now(),this.deltaTime=0,this._autoUpdate=!1,this.once("modelLoaded",(()=>this.init(t)))}static from(t,e){const i=new this(e);return Te.setupLive2DModel(i,t,e).then((()=>i))}static fromSync(t,e){const i=new this(e);return Te.setupLive2DModel(i,t,e).then(null==e?void 0:e.onLoad).catch(null==e?void 0:e.onError),i}static registerTicker(t){Oe=t}get autoUpdate(){return this._autoUpdate}set autoUpdate(t){var e;Oe||(Oe=null==(e=window.PIXI)?void 0:e.Ticker),t?this._destroyed||(Oe?(Oe.shared.add(this.onTickerUpdate,this),this._autoUpdate=!0):ee.warn(this.tag,"No Ticker registered, please call Live2DModel.registerTicker(Ticker).")):(null==Oe||Oe.shared.remove(this.onTickerUpdate,this),this._autoUpdate=!1)}init(t){this.tag=`Live2DModel(${this.internalModel.settings.name})`;const e=Object.assign({autoUpdate:!0,autoInteract:!0},t);e.autoInteract&&(this.interactive=!0),this.autoInteract=e.autoInteract,this.autoUpdate=e.autoUpdate}onAnchorChange(){this.pivot.set(this.anchor.x*this.internalModel.width,this.anchor.y*this.internalModel.height)}motion(t,e,i){return void 0===e?this.internalModel.motionManager.startRandomMotion(t,i):this.internalModel.motionManager.startMotion(t,e,i)}expression(t){return this.internalModel.motionManager.expressionManager?void 0===t?this.internalModel.motionManager.expressionManager.setRandomExpression():this.internalModel.motionManager.expressionManager.setExpression(t):Promise.resolve(!1)}focus(t,e,i=!1){Be.x=t,Be.y=e,this.toModelPosition(Be,Be,!0);let s=Be.x/this.internalModel.originalWidth*2-1,r=Be.y/this.internalModel.originalHeight*2-1,a=Math.atan2(r,s);this.internalModel.focusController.focus(Math.cos(a),-Math.sin(a),i)}tap(t,e){const i=this.hitTest(t,e);i.length&&(ee.log(this.tag,"Hit",i),this.emit("hit",i))}hitTest(t,e){return Be.x=t,Be.y=e,this.toModelPosition(Be,Be),this.internalModel.hitTest(Be.x,Be.y)}toModelPosition(t,e=t.clone(),i){return i||(this._recursivePostUpdateTransform(),this.parent?this.displayObjectUpdateTransform():(this.parent=this._tempDisplayObjectParent,this.displayObjectUpdateTransform(),this.parent=null)),this.transform.worldTransform.applyInverse(t,e),this.internalModel.localTransform.applyInverse(e,e),e}containsPoint(t){return this.getBounds(!0).contains(t.x,t.y)}_calculateBounds(){this._bounds.addFrame(this.transform,0,0,this.internalModel.width,this.internalModel.height)}onTickerUpdate(){this.update(Oe.shared.deltaMS)}update(t){this.deltaTime+=t,this.elapsedTime+=t}_render(t){this.registerInteraction(t.plugins.interaction),t.batch.reset(),t.geometry.reset(),t.shader.reset(),t.state.reset();let e=!1;this.glContextID!==t.CONTEXT_UID&&(this.glContextID=t.CONTEXT_UID,this.internalModel.updateWebGLContext(t.gl,this.glContextID),e=!0);for(let r=0;re.destroy(t.baseTexture))),this.internalModel.destroy(),super.destroy(t)}}se(ke,[Ee]);const Ue=class{static resolveURL(t,e){var i;const s=null==(i=Ue.filesMap[t])?void 0:i[e];if(void 0===s)throw new Error("Cannot find this file from uploaded files: "+e);return s}static upload(t,i){return __async(this,null,(function*(){const s={};for(const r of i.getDefinedFiles()){const a=decodeURI(e.url.resolve(i.url,r)),o=t.find((t=>t.webkitRelativePath===a));o&&(s[r]=URL.createObjectURL(o))}Ue.filesMap[i._objectURL]=s}))}static createSettings(t){return __async(this,null,(function*(){const e=t.find((t=>t.name.endsWith("model.json")||t.name.endsWith("model3.json")));if(!e)throw new TypeError("Settings file not found");const i=yield Ue.readText(e),s=JSON.parse(i);s.url=e.webkitRelativePath;const r=Te.findRuntime(s);if(!r)throw new Error("Unknown settings JSON");const a=r.createModelSettings(s);return a._objectURL=URL.createObjectURL(e),a}))}static readText(t){return __async(this,null,(function*(){return new Promise(((e,i)=>{const s=new FileReader;s.onload=()=>e(s.result),s.onerror=i,s.readAsText(t,"utf8")}))}))}};let Ne=Ue;Ne.filesMap={},Ne.factory=(t,e)=>__async(this,null,(function*(){if(Array.isArray(t.source)&&t.source[0]instanceof File){const e=t.source;let i=e.settings;if(i){if(!i._objectURL)throw new Error('"_objectURL" must be specified in ModelSettings')}else i=yield Ue.createSettings(e);i.validateFiles(e.map((t=>encodeURI(t.webkitRelativePath)))),yield Ue.upload(e,i),i.resolveURL=function(t){return Ue.resolveURL(this._objectURL,t)},t.source=i,t.live2dModel.once("modelLoaded",(t=>{t.once("destroy",(function(){const t=this.settings._objectURL;if(URL.revokeObjectURL(t),Ue.filesMap[t])for(const e of Object.values(Ue.filesMap[t]))URL.revokeObjectURL(e);delete Ue.filesMap[t]}))}))}return e()})),Te.live2DModelMiddlewares.unshift(Ne.factory);const Ve=class{static unzip(t,i){return __async(this,null,(function*(){const s=yield Ve.getFilePaths(t),r=[];for(const t of i.getDefinedFiles()){const a=decodeURI(e.url.resolve(i.url,t));s.includes(a)&&r.push(a)}const a=yield Ve.getFiles(t,r);for(let t=0;tt.endsWith("model.json")||t.endsWith("model3.json")));if(!e)throw new Error("Settings file not found");const i=yield Ve.readText(t,e);if(!i)throw new Error("Empty settings file: "+e);const s=JSON.parse(i);s.url=e;const r=Te.findRuntime(s);if(!r)throw new Error("Unknown settings JSON");return r.createModelSettings(s)}))}static zipReader(t,e){return __async(this,null,(function*(){throw new Error("Not implemented")}))}static getFilePaths(t){return __async(this,null,(function*(){throw new Error("Not implemented")}))}static getFiles(t,e){return __async(this,null,(function*(){throw new Error("Not implemented")}))}static readText(t,e){return __async(this,null,(function*(){throw new Error("Not implemented")}))}static releaseReader(t){}};let je=Ve;if(je.ZIP_PROTOCOL="zip://",je.uid=0,je.factory=(t,e)=>__async(this,null,(function*(){const i=t.source;let s,r,a;if("string"==typeof i&&(i.endsWith(".zip")||i.startsWith(Ve.ZIP_PROTOCOL))?(s=i.startsWith(Ve.ZIP_PROTOCOL)?i.slice(Ve.ZIP_PROTOCOL.length):i,r=yield ve.load({url:s,type:"blob",target:t.live2dModel})):Array.isArray(i)&&1===i.length&&i[0]instanceof File&&i[0].name.endsWith(".zip")&&(r=i[0],s=URL.createObjectURL(r),a=i.settings),r){if(!r.size)throw new Error("Empty zip file");const e=yield Ve.zipReader(r,s);a||(a=yield Ve.createSettings(e)),a._objectURL=Ve.ZIP_PROTOCOL+Ve.uid+"/"+a.url;const i=yield Ve.unzip(e,a);i.settings=a,t.source=i,s.startsWith("blob:")&&t.live2dModel.once("modelLoaded",(t=>{t.once("destroy",(function(){URL.revokeObjectURL(s)}))})),Ve.releaseReader(e)}return e()})),Te.live2DModelMiddlewares.unshift(je.factory),!window.Live2DCubismCore)throw new Error("Could not find Cubism 4 runtime. This plugin requires live2dcubismcore.js to be loaded.");class Ge extends oe{constructor(t,e){var i;super(t,e),this.queueManager=new st,this.definitions=null!=(i=t.expressions)?i:[],this.init()}isFinished(){return this.queueManager.isFinished()}getExpressionIndex(t){return this.definitions.findIndex((e=>e.Name===t))}getExpressionFile(t){return t.File}createExpression(t,e){return O.create(t)}_setExpression(t){return this.queueManager.startMotion(t,!1,performance.now())}stopAllExpressions(){this.queueManager.stopAllMotions()}updateParameters(t,e){return this.queueManager.doUpdateMotion(t,e)}}class Xe extends le{constructor(t){if(super(t),!Xe.isValidJSON(t))throw new TypeError("Invalid JSON.");Object.assign(this,new Ht(t))}static isValidJSON(t){var e;return!!(null==t?void 0:t.FileReferences)&&"string"==typeof t.FileReferences.Moc&&(null==(e=t.FileReferences.Textures)?void 0:e.length)>0&&t.FileReferences.Textures.every((t=>"string"==typeof t))}replaceFiles(t){if(super.replaceFiles(t),this.motions)for(const[e,i]of Object.entries(this.motions))for(let s=0;s{this.emit("motion:"+e)}))}isFinished(){return this.queueManager.isFinished()}_startMotion(t,e){return t.setFinishedMotionHandler(e),this.queueManager.stopAllMotions(),this.queueManager.startMotion(t,!1,performance.now())}_stopAllMotions(){this.queueManager.stopAllMotions()}createMotion(e,i,s){const r=et.create(e),a=new H(e),o=(i===this.groups.idle?t.config.idleMotionFadingDuration:t.config.motionFadingDuration)/1e3;return void 0===a.getMotionFadeInTime()&&r.setFadeInTime(s.FadeInTime>0?s.FadeInTime:o),void 0===a.getMotionFadeOutTime()&&r.setFadeOutTime(s.FadeOutTime>0?s.FadeOutTime:o),r.setEffectIds(this.eyeBlinkIds,this.lipSyncIds),r}getMotionFile(t){return t.File}getMotionName(t){return t.File}getSoundFile(t){return t.Sound}updateParameters(t,e){return this.queueManager.doUpdateMotion(t,e)}destroy(){super.destroy(),this.queueManager.release(),this.queueManager=void 0}}const We=new p;class He extends pe{constructor(t,e,s){super(),this.lipSync=!0,this.breath=a.create(),this.renderer=new Wt,this.idParamAngleX=Yt,this.idParamAngleY=qt,this.idParamAngleZ=$t,this.idParamEyeBallX=Zt,this.idParamEyeBallY=Jt,this.idParamBodyAngleX=Qt,this.idParamBreath=Kt,this.pixelsPerUnit=1,this.centeringTransform=new i.Matrix,this.coreModel=t,this.settings=e,this.motionManager=new ze(e,s),this.init()}init(){var t;super.init(),(null==(t=this.settings.getEyeBlinkParameters())?void 0:t.length)>0&&(this.eyeBlink=l.create(this.settings)),this.breath.setParameters([new o(this.idParamAngleX,0,15,6.5345,.5),new o(this.idParamAngleY,0,8,3.5345,.5),new o(this.idParamAngleZ,0,10,5.5345,.5),new o(this.idParamBodyAngleX,0,4,15.5345,.5),new o(this.idParamBreath,0,.5,3.2345,.5)]),this.renderer.initialize(this.coreModel),this.renderer.setIsPremultipliedAlpha(!0)}getSize(){return[this.coreModel.getModel().canvasinfo.CanvasWidth,this.coreModel.getModel().canvasinfo.CanvasHeight]}getLayout(){const t={};if(this.settings.layout)for(const e of Object.keys(this.settings.layout)){t[e.charAt(0).toLowerCase()+e.slice(1)]=this.settings.layout[e]}return t}setupLayout(){super.setupLayout(),this.pixelsPerUnit=this.coreModel.getModel().canvasinfo.PixelsPerUnit,this.centeringTransform.scale(this.pixelsPerUnit,this.pixelsPerUnit).translate(this.originalWidth/2,this.originalHeight/2)}updateWebGLContext(t,e){this.renderer.firstDraw=!0,this.renderer._bufferData={vertex:null,uv:null,index:null},this.renderer.startUp(t),this.renderer._clippingManager._currentFrameNo=e,this.renderer._clippingManager._maskTexture=void 0,Ot.getInstance()._shaderSets=[]}bindTexture(t,e){this.renderer.bindTexture(t,e)}getHitAreaDefs(){var t,e;return null!=(e=null==(t=this.settings.hitAreas)?void 0:t.map((t=>({id:t.Id,name:t.Name,index:this.coreModel.getDrawableIndex(t.Id)}))))?e:[]}getDrawableIDs(){return this.coreModel.getDrawableIds()}getDrawableIndex(t){return this.coreModel.getDrawableIndex(t)}getDrawableVertices(t){if("string"==typeof t&&-1===(t=this.coreModel.getDrawableIndex(t)))throw new TypeError("Unable to find drawable ID: "+t);const e=this.coreModel.getDrawableVertices(t).slice();for(let i=0;i{!function i(){try{Ze(),t()}catch(s){if(qe--,qe<0){const t=new Error("Failed to start up Cubism 4 framework.");return t.cause=s,void e(t)}ee.log("Cubism4","Startup failed, retrying 10ms later..."),setTimeout(i,10)}}()}))),Ye)}function Ze(t){t=Object.assign({logFunction:console.log,loggingLevel:S.LogLevel_Verbose},t),C.startUp(t),C.initialize()}function Je(){var t;null==(t=this.__moc)||t.release()}Te.registerRuntime({version:4,ready:$e,test:t=>t instanceof Xe||Xe.isValidJSON(t),isValidMoc(t){if(t.byteLength<4)return!1;const e=new Int8Array(t,0,4);return"MOC3"===String.fromCharCode(...e)},createModelSettings:t=>new Xe(t),createCoreModel(t){const e=F.create(t);try{const t=e.createModel();return t.__moc=e,t}catch(i){try{e.release()}catch(s){}throw i}},createInternalModel(t,e,i){const s=new He(t,e,i),r=t;return r.__moc&&(s.__moc=r.__moc,delete r.__moc,s.once("destroy",Je)),s},createPhysics:(t,e)=>gt.create(e),createPose:(t,e)=>u.create(e)}),t.ACubismMotion=R,t.BreathParameterData=o,t.CSM_ASSERT=b,t.Constant=P,t.Cubism4ExpressionManager=Ge,t.Cubism4InternalModel=He,t.Cubism4ModelSettings=Xe,t.Cubism4MotionManager=ze,t.CubismBlendMode=f,t.CubismBreath=a,t.CubismClippingContext=Rt,t.CubismClippingManager_WebGL=At,t.CubismDebug=E,t.CubismExpressionMotion=O,t.CubismEyeBlink=l,t.CubismFramework=C,t.CubismLogDebug=w,t.CubismLogError=T,t.CubismLogInfo=I,t.CubismLogVerbose=function(t,...e){E.print(S.LogLevel_Verbose,"[CSM][V]"+t+"\n",e)},t.CubismLogWarning=L,t.CubismMath=g,t.CubismMatrix44=p,t.CubismMoc=F,t.CubismModel=D,t.CubismModelSettingsJson=Ht,t.CubismModelUserData=B,t.CubismModelUserDataJson=A,t.CubismMotion=et,t.CubismMotionCurve=X,t.CubismMotionCurveTarget=N,t.CubismMotionData=W,t.CubismMotionEvent=z,t.CubismMotionJson=H,t.CubismMotionManager=class extends st{constructor(){super(),this._currentPriority=0,this._reservePriority=0}getCurrentPriority(){return this._currentPriority}getReservePriority(){return this._reservePriority}setReservePriority(t){this._reservePriority=t}startMotionPriority(t,e,i){return i==this._reservePriority&&(this._reservePriority=0),this._currentPriority=i,super.startMotion(t,e,this._userTimeSeconds)}updateMotion(t,e){this._userTimeSeconds+=e;const i=super.doUpdateMotion(t,this._userTimeSeconds);return this.isFinished()&&(this._currentPriority=0),i}reserveMotion(t){return!(t<=this._reservePriority||t<=this._currentPriority)&&(this._reservePriority=t,!0)}},t.CubismMotionPoint=j,t.CubismMotionQueueEntry=it,t.CubismMotionQueueManager=st,t.CubismMotionSegment=G,t.CubismMotionSegmentType=V,t.CubismPhysics=gt,t.CubismPhysicsInput=ht,t.CubismPhysicsJson=ct,t.CubismPhysicsOutput=ut,t.CubismPhysicsParticle=nt,t.CubismPhysicsRig=dt,t.CubismPhysicsSource=ot,t.CubismPhysicsSubRig=lt,t.CubismPhysicsTargetType=at,t.CubismPose=u,t.CubismRenderTextureResource=Bt,t.CubismRenderer=_,t.CubismRenderer_WebGL=Wt,t.CubismShader_WebGL=Ot,t.CubismTextureColor=y,t.CubismVector2=c,t.EvaluationOptionFlag=Y,t.ExpressionBlendType=U,t.ExpressionManager=oe,t.EyeState=h,t.FileLoader=Ne,t.FocusController=ne,t.HitAreaBody="Body",t.HitAreaHead="Head",t.HitAreaPrefix="HitArea",t.InteractionMixin=Ee,t.InternalModel=pe,t.InvalidMotionQueueEntryHandleValue=rt,t.LOGICAL_HEIGHT=2,t.LOGICAL_WIDTH=2,t.Live2DFactory=Te,t.Live2DLoader=ve,t.Live2DModel=ke,t.Live2DTransform=Ae,t.LogLevel=S,t.ModelSettings=le,t.MotionManager=me,t.MotionPreloadStrategy=ce,t.MotionPriority=he,t.MotionState=ue,t.Options=pt,t.ParamAngleX=Yt,t.ParamAngleY=qt,t.ParamAngleZ=$t,t.ParamArmLA="ParamArmLA",t.ParamArmLB="ParamArmLB",t.ParamArmRA="ParamArmRA",t.ParamArmRB="ParamArmRB",t.ParamBaseX="ParamBaseX",t.ParamBaseY="ParamBaseY",t.ParamBodyAngleX=Qt,t.ParamBodyAngleY="ParamBodyAngleY",t.ParamBodyAngleZ="ParamBodyAngleZ",t.ParamBreath=Kt,t.ParamBrowLAngle="ParamBrowLAngle",t.ParamBrowLForm="ParamBrowLForm",t.ParamBrowLX="ParamBrowLX",t.ParamBrowLY="ParamBrowLY",t.ParamBrowRAngle="ParamBrowRAngle",t.ParamBrowRForm="ParamBrowRForm",t.ParamBrowRX="ParamBrowRX",t.ParamBrowRY="ParamBrowRY",t.ParamBustX="ParamBustX",t.ParamBustY="ParamBustY",t.ParamCheek="ParamCheek",t.ParamEyeBallForm="ParamEyeBallForm",t.ParamEyeBallX=Zt,t.ParamEyeBallY=Jt,t.ParamEyeLOpen="ParamEyeLOpen",t.ParamEyeLSmile="ParamEyeLSmile",t.ParamEyeROpen="ParamEyeROpen",t.ParamEyeRSmile="ParamEyeRSmile",t.ParamHairBack="ParamHairBack",t.ParamHairFluffy="ParamHairFluffy",t.ParamHairFront="ParamHairFront",t.ParamHairSide="ParamHairSide",t.ParamHandL="ParamHandL",t.ParamHandR="ParamHandR",t.ParamMouthForm="ParamMouthForm",t.ParamMouthOpenY="ParamMouthOpenY",t.ParamNONE="NONE:",t.ParamShoulderY="ParamShoulderY",t.PartData=d,t.PartsArmLPrefix="Parts01ArmL_",t.PartsArmPrefix="Parts01Arm_",t.PartsArmRPrefix="Parts01ArmR_",t.PartsIdCore="Parts01Core",t.PhysicsJsonEffectiveForces=class{constructor(){this.gravity=new c(0,0),this.wind=new c(0,0)}},t.ShaderNames=kt,t.SoundManager=de,t.VERSION="0.4.0",t.XHRLoader=ye,t.ZipLoader=je,t.applyMixins=se,t.clamp=ie,t.copyArray=function(t,e,i,s,r){const a=e[s];Array.isArray(a)&&(i[r]=a.filter((e=>null!==e&&typeof e===t)))},t.copyProperty=function(t,e,i,s,r){const a=e[s];null!==a&&typeof a===t&&(i[r]=a)},t.csmRect=Tt,t.cubism4Ready=$e,t.folderName=re,t.fragmentShaderSrcMaskInvertedPremultipliedAlpha=zt,t.fragmentShaderSrcMaskPremultipliedAlpha=Xt,t.fragmentShaderSrcPremultipliedAlpha=Gt,t.fragmentShaderSrcsetupMask=Nt,t.logger=ee,t.rand=function(t,e){return Math.random()*(e-t)+t},t.remove=ae,t.startUpCubism4=Ze,t.vertexShaderSrc=Vt,t.vertexShaderSrcMasked=jt,t.vertexShaderSrcSetupMask=Ut,Object.defineProperties(t,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})})); diff --git a/src/live2d/vendor/pixi.min.js b/src/live2d/vendor/pixi.min.js new file mode 100644 index 0000000..02f7b62 --- /dev/null +++ b/src/live2d/vendor/pixi.min.js @@ -0,0 +1,9 @@ +/*! + * pixi.js - v6.5.10 + * Compiled Thu, 06 Jul 2023 15:25:11 UTC + * + * pixi.js is licensed under the MIT License. + * http://www.opensource.org/licenses/mit-license + */ +var PIXI=function(t){"use strict";var e=setTimeout;function r(t){return Boolean(t&&void 0!==t.length)}function i(){}function n(t){if(!(this instanceof n))throw new TypeError("Promises must be constructed via new");if("function"!=typeof t)throw new TypeError("not a function");this._state=0,this._handled=!1,this._value=void 0,this._deferreds=[],l(t,this)}function o(t,e){for(;3===t._state;)t=t._value;0!==t._state?(t._handled=!0,n._immediateFn((function(){var r=1===t._state?e.onFulfilled:e.onRejected;if(null!==r){var i;try{i=r(t._value)}catch(t){return void a(e.promise,t)}s(e.promise,i)}else(1===t._state?s:a)(e.promise,t._value)}))):t._deferreds.push(e)}function s(t,e){try{if(e===t)throw new TypeError("A promise cannot be resolved with itself.");if(e&&("object"==typeof e||"function"==typeof e)){var r=e.then;if(e instanceof n)return t._state=3,t._value=e,void h(t);if("function"==typeof r)return void l((i=r,o=e,function(){i.apply(o,arguments)}),t)}t._state=1,t._value=e,h(t)}catch(e){a(t,e)}var i,o}function a(t,e){t._state=2,t._value=e,h(t)}function h(t){2===t._state&&0===t._deferreds.length&&n._immediateFn((function(){t._handled||n._unhandledRejectionFn(t._value)}));for(var e=0,r=t._deferreds.length;e0?1:-1}),Number.isInteger||(Number.isInteger=function(t){return"number"==typeof t&&isFinite(t)&&Math.floor(t)===t}),globalThis.ArrayBuffer||(globalThis.ArrayBuffer=Array),globalThis.Float32Array||(globalThis.Float32Array=Array),globalThis.Uint32Array||(globalThis.Uint32Array=Array),globalThis.Uint16Array||(globalThis.Uint16Array=Array),globalThis.Uint8Array||(globalThis.Uint8Array=Array),globalThis.Int32Array||(globalThis.Int32Array=Array),t.ENV=void 0,t.RENDERER_TYPE=void 0,t.BUFFER_BITS=void 0,t.BLEND_MODES=void 0,t.DRAW_MODES=void 0,t.FORMATS=void 0,t.TARGETS=void 0,t.TYPES=void 0,t.SAMPLER_TYPES=void 0,t.SCALE_MODES=void 0,t.WRAP_MODES=void 0,t.MIPMAP_MODES=void 0,t.ALPHA_MODES=void 0,t.CLEAR_MODES=void 0,t.GC_MODES=void 0,t.PRECISION=void 0,t.MASK_TYPES=void 0,t.COLOR_MASK_BITS=void 0,t.MSAA_QUALITY=void 0,t.BUFFER_TYPE=void 0,function(t){t[t.WEBGL_LEGACY=0]="WEBGL_LEGACY",t[t.WEBGL=1]="WEBGL",t[t.WEBGL2=2]="WEBGL2"}(t.ENV||(t.ENV={})),function(t){t[t.UNKNOWN=0]="UNKNOWN",t[t.WEBGL=1]="WEBGL",t[t.CANVAS=2]="CANVAS"}(t.RENDERER_TYPE||(t.RENDERER_TYPE={})),function(t){t[t.COLOR=16384]="COLOR",t[t.DEPTH=256]="DEPTH",t[t.STENCIL=1024]="STENCIL"}(t.BUFFER_BITS||(t.BUFFER_BITS={})),function(t){t[t.NORMAL=0]="NORMAL",t[t.ADD=1]="ADD",t[t.MULTIPLY=2]="MULTIPLY",t[t.SCREEN=3]="SCREEN",t[t.OVERLAY=4]="OVERLAY",t[t.DARKEN=5]="DARKEN",t[t.LIGHTEN=6]="LIGHTEN",t[t.COLOR_DODGE=7]="COLOR_DODGE",t[t.COLOR_BURN=8]="COLOR_BURN",t[t.HARD_LIGHT=9]="HARD_LIGHT",t[t.SOFT_LIGHT=10]="SOFT_LIGHT",t[t.DIFFERENCE=11]="DIFFERENCE",t[t.EXCLUSION=12]="EXCLUSION",t[t.HUE=13]="HUE",t[t.SATURATION=14]="SATURATION",t[t.COLOR=15]="COLOR",t[t.LUMINOSITY=16]="LUMINOSITY",t[t.NORMAL_NPM=17]="NORMAL_NPM",t[t.ADD_NPM=18]="ADD_NPM",t[t.SCREEN_NPM=19]="SCREEN_NPM",t[t.NONE=20]="NONE",t[t.SRC_OVER=0]="SRC_OVER",t[t.SRC_IN=21]="SRC_IN",t[t.SRC_OUT=22]="SRC_OUT",t[t.SRC_ATOP=23]="SRC_ATOP",t[t.DST_OVER=24]="DST_OVER",t[t.DST_IN=25]="DST_IN",t[t.DST_OUT=26]="DST_OUT",t[t.DST_ATOP=27]="DST_ATOP",t[t.ERASE=26]="ERASE",t[t.SUBTRACT=28]="SUBTRACT",t[t.XOR=29]="XOR"}(t.BLEND_MODES||(t.BLEND_MODES={})),function(t){t[t.POINTS=0]="POINTS",t[t.LINES=1]="LINES",t[t.LINE_LOOP=2]="LINE_LOOP",t[t.LINE_STRIP=3]="LINE_STRIP",t[t.TRIANGLES=4]="TRIANGLES",t[t.TRIANGLE_STRIP=5]="TRIANGLE_STRIP",t[t.TRIANGLE_FAN=6]="TRIANGLE_FAN"}(t.DRAW_MODES||(t.DRAW_MODES={})),function(t){t[t.RGBA=6408]="RGBA",t[t.RGB=6407]="RGB",t[t.RG=33319]="RG",t[t.RED=6403]="RED",t[t.RGBA_INTEGER=36249]="RGBA_INTEGER",t[t.RGB_INTEGER=36248]="RGB_INTEGER",t[t.RG_INTEGER=33320]="RG_INTEGER",t[t.RED_INTEGER=36244]="RED_INTEGER",t[t.ALPHA=6406]="ALPHA",t[t.LUMINANCE=6409]="LUMINANCE",t[t.LUMINANCE_ALPHA=6410]="LUMINANCE_ALPHA",t[t.DEPTH_COMPONENT=6402]="DEPTH_COMPONENT",t[t.DEPTH_STENCIL=34041]="DEPTH_STENCIL"}(t.FORMATS||(t.FORMATS={})),function(t){t[t.TEXTURE_2D=3553]="TEXTURE_2D",t[t.TEXTURE_CUBE_MAP=34067]="TEXTURE_CUBE_MAP",t[t.TEXTURE_2D_ARRAY=35866]="TEXTURE_2D_ARRAY",t[t.TEXTURE_CUBE_MAP_POSITIVE_X=34069]="TEXTURE_CUBE_MAP_POSITIVE_X",t[t.TEXTURE_CUBE_MAP_NEGATIVE_X=34070]="TEXTURE_CUBE_MAP_NEGATIVE_X",t[t.TEXTURE_CUBE_MAP_POSITIVE_Y=34071]="TEXTURE_CUBE_MAP_POSITIVE_Y",t[t.TEXTURE_CUBE_MAP_NEGATIVE_Y=34072]="TEXTURE_CUBE_MAP_NEGATIVE_Y",t[t.TEXTURE_CUBE_MAP_POSITIVE_Z=34073]="TEXTURE_CUBE_MAP_POSITIVE_Z",t[t.TEXTURE_CUBE_MAP_NEGATIVE_Z=34074]="TEXTURE_CUBE_MAP_NEGATIVE_Z"}(t.TARGETS||(t.TARGETS={})),function(t){t[t.UNSIGNED_BYTE=5121]="UNSIGNED_BYTE",t[t.UNSIGNED_SHORT=5123]="UNSIGNED_SHORT",t[t.UNSIGNED_SHORT_5_6_5=33635]="UNSIGNED_SHORT_5_6_5",t[t.UNSIGNED_SHORT_4_4_4_4=32819]="UNSIGNED_SHORT_4_4_4_4",t[t.UNSIGNED_SHORT_5_5_5_1=32820]="UNSIGNED_SHORT_5_5_5_1",t[t.UNSIGNED_INT=5125]="UNSIGNED_INT",t[t.UNSIGNED_INT_10F_11F_11F_REV=35899]="UNSIGNED_INT_10F_11F_11F_REV",t[t.UNSIGNED_INT_2_10_10_10_REV=33640]="UNSIGNED_INT_2_10_10_10_REV",t[t.UNSIGNED_INT_24_8=34042]="UNSIGNED_INT_24_8",t[t.UNSIGNED_INT_5_9_9_9_REV=35902]="UNSIGNED_INT_5_9_9_9_REV",t[t.BYTE=5120]="BYTE",t[t.SHORT=5122]="SHORT",t[t.INT=5124]="INT",t[t.FLOAT=5126]="FLOAT",t[t.FLOAT_32_UNSIGNED_INT_24_8_REV=36269]="FLOAT_32_UNSIGNED_INT_24_8_REV",t[t.HALF_FLOAT=36193]="HALF_FLOAT"}(t.TYPES||(t.TYPES={})),function(t){t[t.FLOAT=0]="FLOAT",t[t.INT=1]="INT",t[t.UINT=2]="UINT"}(t.SAMPLER_TYPES||(t.SAMPLER_TYPES={})),function(t){t[t.NEAREST=0]="NEAREST",t[t.LINEAR=1]="LINEAR"}(t.SCALE_MODES||(t.SCALE_MODES={})),function(t){t[t.CLAMP=33071]="CLAMP",t[t.REPEAT=10497]="REPEAT",t[t.MIRRORED_REPEAT=33648]="MIRRORED_REPEAT"}(t.WRAP_MODES||(t.WRAP_MODES={})),function(t){t[t.OFF=0]="OFF",t[t.POW2=1]="POW2",t[t.ON=2]="ON",t[t.ON_MANUAL=3]="ON_MANUAL"}(t.MIPMAP_MODES||(t.MIPMAP_MODES={})),function(t){t[t.NPM=0]="NPM",t[t.UNPACK=1]="UNPACK",t[t.PMA=2]="PMA",t[t.NO_PREMULTIPLIED_ALPHA=0]="NO_PREMULTIPLIED_ALPHA",t[t.PREMULTIPLY_ON_UPLOAD=1]="PREMULTIPLY_ON_UPLOAD",t[t.PREMULTIPLY_ALPHA=2]="PREMULTIPLY_ALPHA",t[t.PREMULTIPLIED_ALPHA=2]="PREMULTIPLIED_ALPHA"}(t.ALPHA_MODES||(t.ALPHA_MODES={})),function(t){t[t.NO=0]="NO",t[t.YES=1]="YES",t[t.AUTO=2]="AUTO",t[t.BLEND=0]="BLEND",t[t.CLEAR=1]="CLEAR",t[t.BLIT=2]="BLIT"}(t.CLEAR_MODES||(t.CLEAR_MODES={})),function(t){t[t.AUTO=0]="AUTO",t[t.MANUAL=1]="MANUAL"}(t.GC_MODES||(t.GC_MODES={})),function(t){t.LOW="lowp",t.MEDIUM="mediump",t.HIGH="highp"}(t.PRECISION||(t.PRECISION={})),function(t){t[t.NONE=0]="NONE",t[t.SCISSOR=1]="SCISSOR",t[t.STENCIL=2]="STENCIL",t[t.SPRITE=3]="SPRITE",t[t.COLOR=4]="COLOR"}(t.MASK_TYPES||(t.MASK_TYPES={})),function(t){t[t.RED=1]="RED",t[t.GREEN=2]="GREEN",t[t.BLUE=4]="BLUE",t[t.ALPHA=8]="ALPHA"}(t.COLOR_MASK_BITS||(t.COLOR_MASK_BITS={})),function(t){t[t.NONE=0]="NONE",t[t.LOW=2]="LOW",t[t.MEDIUM=4]="MEDIUM",t[t.HIGH=8]="HIGH"}(t.MSAA_QUALITY||(t.MSAA_QUALITY={})),function(t){t[t.ELEMENT_ARRAY_BUFFER=34963]="ELEMENT_ARRAY_BUFFER",t[t.ARRAY_BUFFER=34962]="ARRAY_BUFFER",t[t.UNIFORM_BUFFER=35345]="UNIFORM_BUFFER"}(t.BUFFER_TYPE||(t.BUFFER_TYPE={}));var E={createCanvas:function(t,e){var r=document.createElement("canvas");return r.width=t,r.height=e,r},getWebGLRenderingContext:function(){return WebGLRenderingContext},getNavigator:function(){return navigator},getBaseUrl:function(){var t;return null!==(t=document.baseURI)&&void 0!==t?t:window.location.href},fetch:function(t,e){return fetch(t,e)}},b=/iPhone/i,x=/iPod/i,A=/iPad/i,S=/\biOS-universal(?:.+)Mac\b/i,R=/\bAndroid(?:.+)Mobile\b/i,O=/Android/i,M=/(?:SD4930UR|\bSilk(?:.+)Mobile\b)/i,P=/Silk/i,I=/Windows Phone/i,D=/\bWindows(?:.+)ARM\b/i,w=/BlackBerry/i,C=/BB10/i,N=/Opera Mini/i,F=/\b(CriOS|Chrome)(?:.+)Mobile/i,L=/Mobile(?:.+)Firefox\b/i,B=function(t){return void 0!==t&&"MacIntel"===t.platform&&"number"==typeof t.maxTouchPoints&&t.maxTouchPoints>1&&"undefined"==typeof MSStream},G=function(t){var e={userAgent:"",platform:"",maxTouchPoints:0};t||"undefined"==typeof navigator?"string"==typeof t?e.userAgent=t:t&&t.userAgent&&(e={userAgent:t.userAgent,platform:t.platform,maxTouchPoints:t.maxTouchPoints||0}):e={userAgent:navigator.userAgent,platform:navigator.platform,maxTouchPoints:navigator.maxTouchPoints||0};var r=e.userAgent,i=r.split("[FBAN");void 0!==i[1]&&(r=i[0]),void 0!==(i=r.split("Twitter"))[1]&&(r=i[0]);var n=function(t){return function(e){return e.test(t)}}(r),o={apple:{phone:n(b)&&!n(I),ipod:n(x),tablet:!n(b)&&(n(A)||B(e))&&!n(I),universal:n(S),device:(n(b)||n(x)||n(A)||n(S)||B(e))&&!n(I)},amazon:{phone:n(M),tablet:!n(M)&&n(P),device:n(M)||n(P)},android:{phone:!n(I)&&n(M)||!n(I)&&n(R),tablet:!n(I)&&!n(M)&&!n(R)&&(n(P)||n(O)),device:!n(I)&&(n(M)||n(P)||n(R)||n(O))||n(/\bokhttp\b/i)},windows:{phone:n(I),tablet:n(D),device:n(I)||n(D)},other:{blackberry:n(w),blackberry10:n(C),opera:n(N),firefox:n(L),chrome:n(F),device:n(w)||n(C)||n(N)||n(L)||n(F)},any:!1,phone:!1,tablet:!1};return o.any=o.apple.device||o.android.device||o.windows.device||o.other.device,o.phone=o.apple.phone||o.android.phone||o.windows.phone,o.tablet=o.apple.tablet||o.android.tablet||o.windows.tablet,o}(globalThis.navigator),U={ADAPTER:E,MIPMAP_TEXTURES:t.MIPMAP_MODES.POW2,ANISOTROPIC_LEVEL:0,RESOLUTION:1,FILTER_RESOLUTION:1,FILTER_MULTISAMPLE:t.MSAA_QUALITY.NONE,SPRITE_MAX_TEXTURES:function(t){var e,r=!0;(G.tablet||G.phone)&&(G.apple.device&&(e=navigator.userAgent.match(/OS (\d+)_(\d+)?/))&&parseInt(e[1],10)<11&&(r=!1),G.android.device&&(e=navigator.userAgent.match(/Android\s([0-9.]*)/))&&parseInt(e[1],10)<7&&(r=!1));return r?32:4}(),SPRITE_BATCH_SIZE:4096,RENDER_OPTIONS:{view:null,width:800,height:600,autoDensity:!1,backgroundColor:0,backgroundAlpha:1,useContextAlpha:!0,clearBeforeRender:!0,antialias:!1,preserveDrawingBuffer:!1},GC_MODE:t.GC_MODES.AUTO,GC_MAX_IDLE:3600,GC_MAX_CHECK_COUNT:600,WRAP_MODE:t.WRAP_MODES.CLAMP,SCALE_MODE:t.SCALE_MODES.LINEAR,PRECISION_VERTEX:t.PRECISION.HIGH,PRECISION_FRAGMENT:G.apple.device?t.PRECISION.HIGH:t.PRECISION.MEDIUM,CAN_UPLOAD_SAME_BUFFER:!G.apple.device,CREATE_IMAGE_BITMAP:!1,ROUND_PIXELS:!1},k="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function X(t,e,r){return t(r={path:e,exports:{},require:function(t,e){return function(){throw new Error("Dynamic requires are not currently supported by @rollup/plugin-commonjs")}(null==e&&r.path)}},r.exports),r.exports}var j=X((function(t){var e=Object.prototype.hasOwnProperty,r="~";function i(){}function n(t,e,r){this.fn=t,this.context=e,this.once=r||!1}function o(t,e,i,o,s){if("function"!=typeof i)throw new TypeError("The listener must be a function");var a=new n(i,o||t,s),h=r?r+e:e;return t._events[h]?t._events[h].fn?t._events[h]=[t._events[h],a]:t._events[h].push(a):(t._events[h]=a,t._eventsCount++),t}function s(t,e){0==--t._eventsCount?t._events=new i:delete t._events[e]}function a(){this._events=new i,this._eventsCount=0}Object.create&&(i.prototype=Object.create(null),(new i).__proto__||(r=!1)),a.prototype.eventNames=function(){var t,i,n=[];if(0===this._eventsCount)return n;for(i in t=this._events)e.call(t,i)&&n.push(r?i.slice(1):i);return Object.getOwnPropertySymbols?n.concat(Object.getOwnPropertySymbols(t)):n},a.prototype.listeners=function(t){var e=r?r+t:t,i=this._events[e];if(!i)return[];if(i.fn)return[i.fn];for(var n=0,o=i.length,s=new Array(o);n80*r){i=o=t[0],n=s=t[1];for(var p=r;po&&(o=a),h>s&&(s=h);u=0!==(u=Math.max(o-i,s-n))?32767/u:0}return q(d,f,r,i,n,u,0),f}function z(t,e,r,i,n){var o,s;if(n===vt(t,e,r,i)>0)for(o=e;o=e;o-=i)s=ft(o,t[o],t[o+1],s);return s&&at(s,s.next)&&(pt(s),s=s.next),s}function W(t,e){if(!t)return t;e||(e=t);var r,i=t;do{if(r=!1,i.steiner||!at(i,i.next)&&0!==st(i.prev,i,i.next))i=i.next;else{if(pt(i),(i=e=i.prev)===i.next)break;r=!0}}while(r||i!==e);return e}function q(t,e,r,i,n,o,s){if(t){!s&&o&&function(t,e,r,i){var n=t;do{0===n.z&&(n.z=rt(n.x,n.y,e,r,i)),n.prevZ=n.prev,n.nextZ=n.next,n=n.next}while(n!==t);n.prevZ.nextZ=null,n.prevZ=null,function(t){var e,r,i,n,o,s,a,h,u=1;do{for(r=t,t=null,o=null,s=0;r;){for(s++,i=r,a=0,e=0;e0||h>0&&i;)0!==a&&(0===h||!i||r.z<=i.z)?(n=r,r=r.nextZ,a--):(n=i,i=i.nextZ,h--),o?o.nextZ=n:t=n,n.prevZ=o,o=n;r=i}o.nextZ=null,u*=2}while(s>1)}(n)}(t,i,n,o);for(var a,h,u=t;t.prev!==t.next;)if(a=t.prev,h=t.next,o?Z(t,i,n,o):K(t))e.push(a.i/r|0),e.push(t.i/r|0),e.push(h.i/r|0),pt(t),t=h.next,u=h.next;else if((t=h)===u){s?1===s?q(t=Q(W(t),e,r),e,r,i,n,o,2):2===s&&J(t,e,r,i,n,o):q(W(t),e,r,i,n,o,1);break}}}function K(t){var e=t.prev,r=t,i=t.next;if(st(e,r,i)>=0)return!1;for(var n=e.x,o=r.x,s=i.x,a=e.y,h=r.y,u=i.y,l=no?n>s?n:s:o>s?o:s,f=a>h?a>u?a:u:h>u?h:u,p=i.next;p!==e;){if(p.x>=l&&p.x<=d&&p.y>=c&&p.y<=f&&nt(n,a,o,h,s,u,p.x,p.y)&&st(p.prev,p,p.next)>=0)return!1;p=p.next}return!0}function Z(t,e,r,i){var n=t.prev,o=t,s=t.next;if(st(n,o,s)>=0)return!1;for(var a=n.x,h=o.x,u=s.x,l=n.y,c=o.y,d=s.y,f=ah?a>u?a:u:h>u?h:u,v=l>c?l>d?l:d:c>d?c:d,m=rt(f,p,e,r,i),y=rt(_,v,e,r,i),g=t.prevZ,T=t.nextZ;g&&g.z>=m&&T&&T.z<=y;){if(g.x>=f&&g.x<=_&&g.y>=p&&g.y<=v&&g!==n&&g!==s&&nt(a,l,h,c,u,d,g.x,g.y)&&st(g.prev,g,g.next)>=0)return!1;if(g=g.prevZ,T.x>=f&&T.x<=_&&T.y>=p&&T.y<=v&&T!==n&&T!==s&&nt(a,l,h,c,u,d,T.x,T.y)&&st(T.prev,T,T.next)>=0)return!1;T=T.nextZ}for(;g&&g.z>=m;){if(g.x>=f&&g.x<=_&&g.y>=p&&g.y<=v&&g!==n&&g!==s&&nt(a,l,h,c,u,d,g.x,g.y)&&st(g.prev,g,g.next)>=0)return!1;g=g.prevZ}for(;T&&T.z<=y;){if(T.x>=f&&T.x<=_&&T.y>=p&&T.y<=v&&T!==n&&T!==s&&nt(a,l,h,c,u,d,T.x,T.y)&&st(T.prev,T,T.next)>=0)return!1;T=T.nextZ}return!0}function Q(t,e,r){var i=t;do{var n=i.prev,o=i.next.next;!at(n,o)&&ht(n,i,i.next,o)&&ct(n,o)&&ct(o,n)&&(e.push(n.i/r|0),e.push(i.i/r|0),e.push(o.i/r|0),pt(i),pt(i.next),i=t=o),i=i.next}while(i!==t);return W(i)}function J(t,e,r,i,n,o){var s=t;do{for(var a=s.next.next;a!==s.prev;){if(s.i!==a.i&&ot(s,a)){var h=dt(s,a);return s=W(s,s.next),h=W(h,h.next),q(s,e,r,i,n,o,0),void q(h,e,r,i,n,o,0)}a=a.next}s=s.next}while(s!==t)}function $(t,e){return t.x-e.x}function tt(t,e){var r=function(t,e){var r,i=e,n=t.x,o=t.y,s=-1/0;do{if(o<=i.y&&o>=i.next.y&&i.next.y!==i.y){var a=i.x+(o-i.y)*(i.next.x-i.x)/(i.next.y-i.y);if(a<=n&&a>s&&(s=a,r=i.x=i.x&&i.x>=l&&n!==i.x&&nt(or.x||i.x===r.x&&et(r,i)))&&(r=i,d=h)),i=i.next}while(i!==u);return r}(t,e);if(!r)return e;var i=dt(r,t);return W(i,i.next),W(r,r.next)}function et(t,e){return st(t.prev,t,e.prev)<0&&st(e.next,t,t.next)<0}function rt(t,e,r,i,n){return(t=1431655765&((t=858993459&((t=252645135&((t=16711935&((t=(t-r)*n|0)|t<<8))|t<<4))|t<<2))|t<<1))|(e=1431655765&((e=858993459&((e=252645135&((e=16711935&((e=(e-i)*n|0)|e<<8))|e<<4))|e<<2))|e<<1))<<1}function it(t){var e=t,r=t;do{(e.x=(t-s)*(o-a)&&(t-s)*(i-a)>=(r-s)*(e-a)&&(r-s)*(o-a)>=(n-s)*(i-a)}function ot(t,e){return t.next.i!==e.i&&t.prev.i!==e.i&&!function(t,e){var r=t;do{if(r.i!==t.i&&r.next.i!==t.i&&r.i!==e.i&&r.next.i!==e.i&&ht(r,r.next,t,e))return!0;r=r.next}while(r!==t);return!1}(t,e)&&(ct(t,e)&&ct(e,t)&&function(t,e){var r=t,i=!1,n=(t.x+e.x)/2,o=(t.y+e.y)/2;do{r.y>o!=r.next.y>o&&r.next.y!==r.y&&n<(r.next.x-r.x)*(o-r.y)/(r.next.y-r.y)+r.x&&(i=!i),r=r.next}while(r!==t);return i}(t,e)&&(st(t.prev,t,e.prev)||st(t,e.prev,e))||at(t,e)&&st(t.prev,t,t.next)>0&&st(e.prev,e,e.next)>0)}function st(t,e,r){return(e.y-t.y)*(r.x-e.x)-(e.x-t.x)*(r.y-e.y)}function at(t,e){return t.x===e.x&&t.y===e.y}function ht(t,e,r,i){var n=lt(st(t,e,r)),o=lt(st(t,e,i)),s=lt(st(r,i,t)),a=lt(st(r,i,e));return n!==o&&s!==a||(!(0!==n||!ut(t,r,e))||(!(0!==o||!ut(t,i,e))||(!(0!==s||!ut(r,t,i))||!(0!==a||!ut(r,e,i)))))}function ut(t,e,r){return e.x<=Math.max(t.x,r.x)&&e.x>=Math.min(t.x,r.x)&&e.y<=Math.max(t.y,r.y)&&e.y>=Math.min(t.y,r.y)}function lt(t){return t>0?1:t<0?-1:0}function ct(t,e){return st(t.prev,t,t.next)<0?st(t,e,t.next)>=0&&st(t,t.prev,e)>=0:st(t,e,t.prev)<0||st(t,t.next,e)<0}function dt(t,e){var r=new _t(t.i,t.x,t.y),i=new _t(e.i,e.x,e.y),n=t.next,o=e.prev;return t.next=e,e.prev=t,r.next=n,n.prev=r,i.next=r,r.prev=i,o.next=i,i.prev=o,i}function ft(t,e,r,i){var n=new _t(t,e,r);return i?(n.next=i.next,n.prev=i,i.next.prev=n,i.next=n):(n.prev=n,n.next=n),n}function pt(t){t.next.prev=t.prev,t.prev.next=t.next,t.prevZ&&(t.prevZ.nextZ=t.nextZ),t.nextZ&&(t.nextZ.prevZ=t.prevZ)}function _t(t,e,r){this.i=t,this.x=e,this.y=r,this.prev=null,this.next=null,this.z=0,this.prevZ=null,this.nextZ=null,this.steiner=!1}function vt(t,e,r,i){for(var n=0,o=e,s=r-i;o0&&(i+=t[n-1].length,r.holes.push(i))}return r},H.default=Y;var mt=X((function(t,e){!function(r){var i=e&&!e.nodeType&&e,n=t&&!t.nodeType&&t,o="object"==typeof k&&k;o.global!==o&&o.window!==o&&o.self!==o||(r=o);var s,a,h=2147483647,u=36,l=/^xn--/,c=/[^\x20-\x7E]/,d=/[\x2E\u3002\uFF0E\uFF61]/g,f={overflow:"Overflow: input needs wider integers to process","not-basic":"Illegal input >= 0x80 (not a basic code point)","invalid-input":"Invalid input"},p=Math.floor,_=String.fromCharCode;function v(t){throw RangeError(f[t])}function m(t,e){for(var r=t.length,i=[];r--;)i[r]=e(t[r]);return i}function y(t,e){var r=t.split("@"),i="";return r.length>1&&(i=r[0]+"@",t=r[1]),i+m((t=t.replace(d,".")).split("."),e).join(".")}function g(t){for(var e,r,i=[],n=0,o=t.length;n=55296&&e<=56319&&n65535&&(e+=_((t-=65536)>>>10&1023|55296),t=56320|1023&t),e+=_(t)})).join("")}function E(t,e){return t+22+75*(t<26)-((0!=e)<<5)}function b(t,e,r){var i=0;for(t=r?p(t/700):t>>1,t+=p(t/e);t>455;i+=u)t=p(t/35);return p(i+36*t/(t+38))}function x(t){var e,r,i,n,o,s,a,l,c,d,f,_=[],m=t.length,y=0,g=128,E=72;for((r=t.lastIndexOf("-"))<0&&(r=0),i=0;i=128&&v("not-basic"),_.push(t.charCodeAt(i));for(n=r>0?r+1:0;n=m&&v("invalid-input"),((l=(f=t.charCodeAt(n++))-48<10?f-22:f-65<26?f-65:f-97<26?f-97:u)>=u||l>p((h-y)/s))&&v("overflow"),y+=l*s,!(l<(c=a<=E?1:a>=E+26?26:a-E));a+=u)s>p(h/(d=u-c))&&v("overflow"),s*=d;E=b(y-o,e=_.length+1,0==o),p(y/e)>h-g&&v("overflow"),g+=p(y/e),y%=e,_.splice(y++,0,g)}return T(_)}function A(t){var e,r,i,n,o,s,a,l,c,d,f,m,y,T,x,A=[];for(m=(t=g(t)).length,e=128,r=0,o=72,s=0;s=e&&fp((h-r)/(y=i+1))&&v("overflow"),r+=(a-e)*y,e=a,s=0;sh&&v("overflow"),f==e){for(l=r,c=u;!(l<(d=c<=o?1:c>=o+26?26:c-o));c+=u)x=l-d,T=u-d,A.push(_(E(d+x%T,0))),l=p(x/T);A.push(_(E(l,0))),o=b(r,y,i==n),r=0,++i}++r,++e}return A.join("")}if(s={version:"1.3.2",ucs2:{decode:g,encode:T},decode:x,encode:A,toASCII:function(t){return y(t,(function(t){return c.test(t)?"xn--"+A(t):t}))},toUnicode:function(t){return y(t,(function(t){return l.test(t)?x(t.slice(4).toLowerCase()):t}))}},i&&n)if(t.exports==i)n.exports=s;else for(a in s)s.hasOwnProperty(a)&&(i[a]=s[a]);else r.punycode=s}(k)})),yt=function(t){return"string"==typeof t},gt=function(t){return"object"==typeof t&&null!==t},Tt=function(t){return null===t},Et=function(t){return null==t};function bt(t,e){return Object.prototype.hasOwnProperty.call(t,e)}var xt=function(t,e,r,i){e=e||"&",r=r||"=";var n={};if("string"!=typeof t||0===t.length)return n;var o=/\+/g;t=t.split(e);var s=1e3;i&&"number"==typeof i.maxKeys&&(s=i.maxKeys);var a=t.length;s>0&&a>s&&(a=s);for(var h=0;h=0?(u=f.substr(0,p),l=f.substr(p+1)):(u=f,l=""),c=decodeURIComponent(u),d=decodeURIComponent(l),bt(n,c)?Array.isArray(n[c])?n[c].push(d):n[c]=[n[c],d]:n[c]=d}return n},At=function(t){switch(typeof t){case"string":return t;case"boolean":return t?"true":"false";case"number":return isFinite(t)?t:"";default:return""}},St=function(t,e,r,i){return e=e||"&",r=r||"=",null===t&&(t=void 0),"object"==typeof t?Object.keys(t).map((function(i){var n=encodeURIComponent(At(i))+r;return Array.isArray(t[i])?t[i].map((function(t){return n+encodeURIComponent(At(t))})).join(e):n+encodeURIComponent(At(t[i]))})).join(e):i?encodeURIComponent(At(i))+r+encodeURIComponent(At(t)):""},Rt=X((function(t,e){e.decode=e.parse=xt,e.encode=e.stringify=St})),Ot=Ht,Mt=function(t,e){return Ht(t,!1,!0).resolve(e)},Pt=function(t){yt(t)&&(t=Ht(t));if(!(t instanceof It))return It.prototype.format.call(t);return t.format()};function It(){this.protocol=null,this.slashes=null,this.auth=null,this.host=null,this.port=null,this.hostname=null,this.hash=null,this.search=null,this.query=null,this.pathname=null,this.path=null,this.href=null}var Dt=/^([a-z0-9.+-]+:)/i,wt=/:[0-9]*$/,Ct=/^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,Nt=["{","}","|","\\","^","`"].concat(["<",">",'"',"`"," ","\r","\n","\t"]),Ft=["'"].concat(Nt),Lt=["%","/","?",";","#"].concat(Ft),Bt=["/","?","#"],Gt=/^[+a-z0-9A-Z_-]{0,63}$/,Ut=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,kt={javascript:!0,"javascript:":!0},Xt={javascript:!0,"javascript:":!0},jt={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0};function Ht(t,e,r){if(t&>(t)&&t instanceof It)return t;var i=new It;return i.parse(t,e,r),i}It.prototype.parse=function(t,e,r){if(!yt(t))throw new TypeError("Parameter 'url' must be a string, not "+typeof t);var i=t.indexOf("?"),n=-1!==i&&i127?T+="x":T+=g[E];if(!T.match(Gt)){var x=m.slice(0,p),A=m.slice(p+1),S=g.match(Ut);S&&(x.push(S[1]),A.unshift(S[2])),A.length&&(s="/"+A.join(".")+s),this.hostname=x.join(".");break}}}this.hostname.length>255?this.hostname="":this.hostname=this.hostname.toLowerCase(),v||(this.hostname=mt.toASCII(this.hostname));var R=this.port?":"+this.port:"",O=this.hostname||"";this.host=O+R,this.href+=this.host,v&&(this.hostname=this.hostname.substr(1,this.hostname.length-2),"/"!==s[0]&&(s="/"+s))}if(!kt[u])for(p=0,y=Ft.length;p0)&&r.host.split("@"))&&(r.auth=S.shift(),r.host=r.hostname=S.shift());return r.search=t.search,r.query=t.query,Tt(r.pathname)&&Tt(r.search)||(r.path=(r.pathname?r.pathname:"")+(r.search?r.search:"")),r.href=r.format(),r}if(!g.length)return r.pathname=null,r.search?r.path="/"+r.search:r.path=null,r.href=r.format(),r;for(var E=g.slice(-1)[0],b=(r.host||t.host||g.length>1)&&("."===E||".."===E)||""===E,x=0,A=g.length;A>=0;A--)"."===(E=g[A])?g.splice(A,1):".."===E?(g.splice(A,1),x++):x&&(g.splice(A,1),x--);if(!m&&!y)for(;x--;x)g.unshift("..");!m||""===g[0]||g[0]&&"/"===g[0].charAt(0)||g.unshift(""),b&&"/"!==g.join("/").substr(-1)&&g.push("");var S,R=""===g[0]||g[0]&&"/"===g[0].charAt(0);T&&(r.hostname=r.host=R?"":g.length?g.shift():"",(S=!!(r.host&&r.host.indexOf("@")>0)&&r.host.split("@"))&&(r.auth=S.shift(),r.host=r.hostname=S.shift()));return(m=m||r.host&&g.length)&&!R&&g.unshift(""),g.length?r.pathname=g.join("/"):(r.pathname=null,r.path=null),Tt(r.pathname)&&Tt(r.search)||(r.path=(r.pathname?r.pathname:"")+(r.search?r.search:"")),r.auth=t.auth||r.auth,r.slashes=r.slashes||t.slashes,r.href=r.format(),r},It.prototype.parseHost=function(){var t=this.host,e=wt.exec(t);e&&(":"!==(e=e[0])&&(this.port=e.substr(1)),t=t.substr(0,t.length-e.length)),t&&(this.hostname=t)};var Yt={parse:Ot,format:Pt,resolve:Mt};function Vt(t){if("string"!=typeof t)throw new TypeError("Path must be a string. Received "+JSON.stringify(t))}function zt(t){return t.split("?")[0].split("#")[0]}var Wt={toPosix:function(t){return"\\","/",t.replace(new RegExp("\\".replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"g"),"/")},isUrl:function(t){return/^https?:/.test(this.toPosix(t))},isDataUrl:function(t){return/^data:([a-z]+\/[a-z0-9-+.]+(;[a-z0-9-.!#$%*+.{}|~`]+=[a-z0-9-.!#$%*+.{}()_|~`]+)*)?(;base64)?,([a-z0-9!$&',()*+;=\-._~:@\/?%\s<>]*?)$/i.test(t)},hasProtocol:function(t){return/^[^/:]+:\//.test(this.toPosix(t))},getProtocol:function(t){Vt(t),t=this.toPosix(t);var e="",r=/^file:\/\/\//.exec(t),i=/^[^/:]+:\/\//.exec(t),n=/^[^/:]+:\//.exec(t);if(r||i||n){var o=(null==r?void 0:r[0])||(null==i?void 0:i[0])||(null==n?void 0:n[0]);e=o,t=t.slice(o.length)}return e},toAbsolute:function(t,e,r){if(this.isDataUrl(t))return t;var i=zt(this.toPosix(null!=e?e:U.ADAPTER.getBaseUrl())),n=zt(this.toPosix(null!=r?r:this.rootname(i)));return Vt(t),(t=this.toPosix(t)).startsWith("/")?Wt.join(n,t.slice(1)):this.isAbsolute(t)?t:this.join(i,t)},normalize:function(t){if(Vt(t=this.toPosix(t)),0===t.length)return".";var e="",r=t.startsWith("/");this.hasProtocol(t)&&(e=this.rootname(t),t=t.slice(e.length));var i=t.endsWith("/");return(t=function(t,e){for(var r,i="",n=0,o=-1,s=0,a=0;a<=t.length;++a){if(a2){var h=i.lastIndexOf("/");if(h!==i.length-1){-1===h?(i="",n=0):n=(i=i.slice(0,h)).length-1-i.lastIndexOf("/"),o=a,s=0;continue}}else if(2===i.length||1===i.length){i="",n=0,o=a,s=0;continue}}else i.length>0?i+="/"+t.slice(o+1,a):i=t.slice(o+1,a),n=a-o-1;o=a,s=0}else 46===r&&-1!==s?++s:s=-1}return i}(t)).length>0&&i&&(t+="/"),r?"/"+t:e+t},isAbsolute:function(t){return Vt(t),t=this.toPosix(t),!!this.hasProtocol(t)||t.startsWith("/")},join:function(){for(var t,e,r=arguments,i=[],n=0;n0)if(void 0===e)e=s;else{var a=null!==(t=i[o-1])&&void 0!==t?t:"";this.extname(a)?e+="/../"+s:e+="/"+s}}return void 0===e?".":this.normalize(e)},dirname:function(t){if(Vt(t),0===t.length)return".";for(var e=(t=this.toPosix(t)).charCodeAt(0),r=47===e,i=-1,n=!0,o=this.getProtocol(t),s=t,a=(t=t.slice(o.length)).length-1;a>=1;--a)if(47===(e=t.charCodeAt(a))){if(!n){i=a;break}}else n=!1;return-1===i?r?"/":this.isUrl(s)?o+t:o:r&&1===i?"//":o+t.slice(0,i)},rootname:function(t){Vt(t);var e="";if(e=(t=this.toPosix(t)).startsWith("/")?"/":this.getProtocol(t),this.isUrl(t)){var r=t.indexOf("/",e.length);(e=-1!==r?t.slice(0,r):t).endsWith("/")||(e+="/")}return e},basename:function(t,e){Vt(t),e&&Vt(e),t=this.toPosix(t);var r,i=0,n=-1,o=!0;if(void 0!==e&&e.length>0&&e.length<=t.length){if(e.length===t.length&&e===t)return"";var s=e.length-1,a=-1;for(r=t.length-1;r>=0;--r){var h=t.charCodeAt(r);if(47===h){if(!o){i=r+1;break}}else-1===a&&(o=!1,a=r+1),s>=0&&(h===e.charCodeAt(s)?-1==--s&&(n=r):(s=-1,n=a))}return i===n?n=a:-1===n&&(n=t.length),t.slice(i,n)}for(r=t.length-1;r>=0;--r)if(47===t.charCodeAt(r)){if(!o){i=r+1;break}}else-1===n&&(o=!1,n=r+1);return-1===n?"":t.slice(i,n)},extname:function(t){Vt(t);for(var e=-1,r=0,i=-1,n=!0,o=0,s=(t=this.toPosix(t)).length-1;s>=0;--s){var a=t.charCodeAt(s);if(47!==a)-1===i&&(n=!1,i=s+1),46===a?-1===e?e=s:1!==o&&(o=1):-1!==e&&(o=-1);else if(!n){r=s+1;break}}return-1===e||-1===i||0===o||1===o&&e===i-1&&e===r+1?"":t.slice(e,i)},parse:function(t){Vt(t);var e={root:"",dir:"",base:"",ext:"",name:""};if(0===t.length)return e;var r,i=(t=this.toPosix(t)).charCodeAt(0),n=this.isAbsolute(t);e.root=this.rootname(t),r=n||this.hasProtocol(t)?1:0;for(var o=-1,s=0,a=-1,h=!0,u=t.length-1,l=0;u>=r;--u)if(47!==(i=t.charCodeAt(u)))-1===a&&(h=!1,a=u+1),46===i?-1===o?o=u:1!==l&&(l=1):-1!==o&&(l=-1);else if(!h){s=u+1;break}return-1===o||-1===a||0===l||1===l&&o===a-1&&o===s+1?-1!==a&&(e.base=e.name=0===s&&n?t.slice(1,a):t.slice(s,a)):(0===s&&n?(e.name=t.slice(1,o),e.base=t.slice(1,a)):(e.name=t.slice(s,o),e.base=t.slice(s,a)),e.ext=t.slice(o,a)),e.dir=this.dirname(t),e},sep:"/",delimiter:":"};U.RETINA_PREFIX=/@([0-9\.]+)x/,U.FAIL_IF_MAJOR_PERFORMANCE_CAVEAT=!1;var qt,Kt=!1;function Zt(t){var e;if(!Kt){if(U.ADAPTER.getNavigator().userAgent.toLowerCase().indexOf("chrome")>-1){var r=["\n %c %c %c PixiJS 6.5.10 - ✰ "+t+" ✰ %c %c http://www.pixijs.com/ %c %c ♥%c♥%c♥ \n\n","background: #ff66a5; padding:5px 0;","background: #ff66a5; padding:5px 0;","color: #ff66a5; background: #030307; padding:5px 0;","background: #ff66a5; padding:5px 0;","background: #ffc3dc; padding:5px 0;","background: #ff66a5; padding:5px 0;","color: #ff2424; background: #fff; padding:5px 0;","color: #ff2424; background: #fff; padding:5px 0;","color: #ff2424; background: #fff; padding:5px 0;"];(e=globalThis.console).log.apply(e,r)}else globalThis.console&&globalThis.console.log("PixiJS 6.5.10 - "+t+" - http://www.pixijs.com/");Kt=!0}}function Qt(){return void 0===qt&&(qt=function(){var t={stencil:!0,failIfMajorPerformanceCaveat:U.FAIL_IF_MAJOR_PERFORMANCE_CAVEAT};try{if(!U.ADAPTER.getWebGLRenderingContext())return!1;var e=U.ADAPTER.createCanvas(),r=e.getContext("webgl",t)||e.getContext("experimental-webgl",t),i=!(!r||!r.getContextAttributes().stencil);if(r){var n=r.getExtension("WEBGL_lose_context");n&&n.loseContext()}return r=null,i}catch(t){return!1}}()),qt}var Jt={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",goldenrod:"#daa520",gold:"#ffd700",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavenderblush:"#fff0f5",lavender:"#e6e6fa",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",rebeccapurple:"#663399",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"};function $t(t,e){return void 0===e&&(e=[]),e[0]=(t>>16&255)/255,e[1]=(t>>8&255)/255,e[2]=(255&t)/255,e}function te(t){var e=t.toString(16);return"#"+("000000".substring(0,6-e.length)+e)}function ee(t){return"string"==typeof t&&"#"===(t=Jt[t.toLowerCase()]||t)[0]&&(t=t.slice(1)),parseInt(t,16)}var re=function(){for(var e=[],r=[],i=0;i<32;i++)e[i]=i,r[i]=i;e[t.BLEND_MODES.NORMAL_NPM]=t.BLEND_MODES.NORMAL,e[t.BLEND_MODES.ADD_NPM]=t.BLEND_MODES.ADD,e[t.BLEND_MODES.SCREEN_NPM]=t.BLEND_MODES.SCREEN,r[t.BLEND_MODES.NORMAL]=t.BLEND_MODES.NORMAL_NPM,r[t.BLEND_MODES.ADD]=t.BLEND_MODES.ADD_NPM,r[t.BLEND_MODES.SCREEN]=t.BLEND_MODES.SCREEN_NPM;var n=[];return n.push(r),n.push(e),n}();function ie(t,e){return re[e?1:0][t]}function ne(t,e,r,i){return r=r||new Float32Array(4),i||void 0===i?(r[0]=t[0]*e,r[1]=t[1]*e,r[2]=t[2]*e):(r[0]=t[0],r[1]=t[1],r[2]=t[2]),r[3]=e,r}function oe(t,e){if(1===e)return(255*e<<24)+t;if(0===e)return 0;var r=t>>16&255,i=t>>8&255,n=255&t;return(255*e<<24)+((r=r*e+.5|0)<<16)+((i=i*e+.5|0)<<8)+(n*e+.5|0)}function se(t,e,r,i){return(r=r||new Float32Array(4))[0]=(t>>16&255)/255,r[1]=(t>>8&255)/255,r[2]=(255&t)/255,(i||void 0===i)&&(r[0]*=e,r[1]*=e,r[2]*=e),r[3]=e,r}function ae(t,e){void 0===e&&(e=null);var r=6*t;if((e=e||new Uint16Array(r)).length!==r)throw new Error("Out buffer length is incorrect, got "+e.length+" and expected "+r);for(var i=0,n=0;i>>1,t|=t>>>2,t|=t>>>4,t|=t>>>8,1+(t|=t>>>16)}function ce(t){return!(t&t-1||!t)}function de(t){var e=(t>65535?1:0)<<4,r=((t>>>=e)>255?1:0)<<3;return e|=r,e|=r=((t>>>=r)>15?1:0)<<2,(e|=r=((t>>>=r)>3?1:0)<<1)|(t>>>=r)>>1}function fe(t,e,r){var i,n=t.length;if(!(e>=n||0===r)){var o=n-(r=e+r>n?n-e:r);for(i=e;i=this.x&&t=this.y&&et.right?t.right:this.right)<=r)return!1;var i=this.yt.bottom?t.bottom:this.bottom)>i}var n=this.left,o=this.right,s=this.top,a=this.bottom;if(o<=n||a<=s)return!1;var h=we[0].set(t.left,t.top),u=we[1].set(t.left,t.bottom),l=we[2].set(t.right,t.top),c=we[3].set(t.right,t.bottom);if(l.x<=h.x||u.y<=h.y)return!1;var d=Math.sign(e.a*e.d-e.b*e.c);if(0===d)return!1;if(e.apply(h,h),e.apply(u,u),e.apply(l,l),e.apply(c,c),Math.max(h.x,u.x,l.x,c.x)<=n||Math.min(h.x,u.x,l.x,c.x)>=o||Math.max(h.y,u.y,l.y,c.y)<=s||Math.min(h.y,u.y,l.y,c.y)>=a)return!1;var f=d*(u.y-h.y),p=d*(h.x-u.x),_=f*n+p*s,v=f*o+p*s,m=f*n+p*a,y=f*o+p*a;if(Math.max(_,v,m,y)<=f*h.x+p*h.y||Math.min(_,v,m,y)>=f*c.x+p*c.y)return!1;var g=d*(h.y-l.y),T=d*(l.x-h.x),E=g*n+T*s,b=g*o+T*s,x=g*n+T*a,A=g*o+T*a;return!(Math.max(E,b,x,A)<=g*h.x+T*h.y||Math.min(E,b,x,A)>=g*c.x+T*c.y)},e.prototype.pad=function(t,e){return void 0===t&&(t=0),void 0===e&&(e=t),this.x-=t,this.y-=e,this.width+=2*t,this.height+=2*e,this},e.prototype.fit=function(t){var e=Math.max(this.x,t.x),r=Math.min(this.x+this.width,t.x+t.width),i=Math.max(this.y,t.y),n=Math.min(this.y+this.height,t.y+t.height);return this.x=e,this.width=Math.max(r-e,0),this.y=i,this.height=Math.max(n-i,0),this},e.prototype.ceil=function(t,e){void 0===t&&(t=1),void 0===e&&(e=.001);var r=Math.ceil((this.x+this.width-e)*t)/t,i=Math.ceil((this.y+this.height-e)*t)/t;return this.x=Math.floor((this.x+e)*t)/t,this.y=Math.floor((this.y+e)*t)/t,this.width=r-this.x,this.height=i-this.y,this},e.prototype.enlarge=function(t){var e=Math.min(this.x,t.x),r=Math.max(this.x+this.width,t.x+t.width),i=Math.min(this.y,t.y),n=Math.max(this.y+this.height,t.y+t.height);return this.x=e,this.width=r-e,this.y=i,this.height=n-i,this},e}(),Ne=function(){function e(e,r,i){void 0===e&&(e=0),void 0===r&&(r=0),void 0===i&&(i=0),this.x=e,this.y=r,this.radius=i,this.type=t.SHAPES.CIRC}return e.prototype.clone=function(){return new e(this.x,this.y,this.radius)},e.prototype.contains=function(t,e){if(this.radius<=0)return!1;var r=this.radius*this.radius,i=this.x-t,n=this.y-e;return(i*=i)+(n*=n)<=r},e.prototype.getBounds=function(){return new Ce(this.x-this.radius,this.y-this.radius,2*this.radius,2*this.radius)},e}(),Fe=function(){function e(e,r,i,n){void 0===e&&(e=0),void 0===r&&(r=0),void 0===i&&(i=0),void 0===n&&(n=0),this.x=e,this.y=r,this.width=i,this.height=n,this.type=t.SHAPES.ELIP}return e.prototype.clone=function(){return new e(this.x,this.y,this.width,this.height)},e.prototype.contains=function(t,e){if(this.width<=0||this.height<=0)return!1;var r=(t-this.x)/this.width,i=(e-this.y)/this.height;return(r*=r)+(i*=i)<=1},e.prototype.getBounds=function(){return new Ce(this.x-this.width,this.y-this.height,this.width,this.height)},e}(),Le=function(){function e(){for(var e=arguments,r=[],i=0;ie!=u>e&&t<(e-a)/(u-a)*(h-s)+s&&(r=!r)}return r},e}(),Be=function(){function e(e,r,i,n,o){void 0===e&&(e=0),void 0===r&&(r=0),void 0===i&&(i=0),void 0===n&&(n=0),void 0===o&&(o=20),this.x=e,this.y=r,this.width=i,this.height=n,this.radius=o,this.type=t.SHAPES.RREC}return e.prototype.clone=function(){return new e(this.x,this.y,this.width,this.height,this.radius)},e.prototype.contains=function(t,e){if(this.width<=0||this.height<=0)return!1;if(t>=this.x&&t<=this.x+this.width&&e>=this.y&&e<=this.y+this.height){var r=Math.max(0,Math.min(this.radius,Math.min(this.width,this.height)/2));if(e>=this.y+r&&e<=this.y+this.height-r||t>=this.x+r&&t<=this.x+this.width-r)return!0;var i=t-(this.x+r),n=e-(this.y+r),o=r*r;if(i*i+n*n<=o)return!0;if((i=t-(this.x+this.width-r))*i+n*n<=o)return!0;if(i*i+(n=e-(this.y+this.height-r))*n<=o)return!0;if((i=t-(this.x+r))*i+n*n<=o)return!0}return!1},e}(),Ge=function(){function t(t,e,r,i){void 0===r&&(r=0),void 0===i&&(i=0),this._x=r,this._y=i,this.cb=t,this.scope=e}return t.prototype.clone=function(e,r){return void 0===e&&(e=this.cb),void 0===r&&(r=this.scope),new t(e,r,this._x,this._y)},t.prototype.set=function(t,e){return void 0===t&&(t=0),void 0===e&&(e=t),this._x===t&&this._y===e||(this._x=t,this._y=e,this.cb.call(this.scope)),this},t.prototype.copyFrom=function(t){return this._x===t.x&&this._y===t.y||(this._x=t.x,this._y=t.y,this.cb.call(this.scope)),this},t.prototype.copyTo=function(t){return t.set(this._x,this._y),t},t.prototype.equals=function(t){return t.x===this._x&&t.y===this._y},Object.defineProperty(t.prototype,"x",{get:function(){return this._x},set:function(t){this._x!==t&&(this._x=t,this.cb.call(this.scope))},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"y",{get:function(){return this._y},set:function(t){this._y!==t&&(this._y=t,this.cb.call(this.scope))},enumerable:!1,configurable:!0}),t}(),Ue=function(){function t(t,e,r,i,n,o){void 0===t&&(t=1),void 0===e&&(e=0),void 0===r&&(r=0),void 0===i&&(i=1),void 0===n&&(n=0),void 0===o&&(o=0),this.array=null,this.a=t,this.b=e,this.c=r,this.d=i,this.tx=n,this.ty=o}return t.prototype.fromArray=function(t){this.a=t[0],this.b=t[1],this.c=t[3],this.d=t[4],this.tx=t[2],this.ty=t[5]},t.prototype.set=function(t,e,r,i,n,o){return this.a=t,this.b=e,this.c=r,this.d=i,this.tx=n,this.ty=o,this},t.prototype.toArray=function(t,e){this.array||(this.array=new Float32Array(9));var r=e||this.array;return t?(r[0]=this.a,r[1]=this.b,r[2]=0,r[3]=this.c,r[4]=this.d,r[5]=0,r[6]=this.tx,r[7]=this.ty,r[8]=1):(r[0]=this.a,r[1]=this.c,r[2]=this.tx,r[3]=this.b,r[4]=this.d,r[5]=this.ty,r[6]=0,r[7]=0,r[8]=1),r},t.prototype.apply=function(t,e){e=e||new De;var r=t.x,i=t.y;return e.x=this.a*r+this.c*i+this.tx,e.y=this.b*r+this.d*i+this.ty,e},t.prototype.applyInverse=function(t,e){e=e||new De;var r=1/(this.a*this.d+this.c*-this.b),i=t.x,n=t.y;return e.x=this.d*r*i+-this.c*r*n+(this.ty*this.c-this.tx*this.d)*r,e.y=this.a*r*n+-this.b*r*i+(-this.ty*this.a+this.tx*this.b)*r,e},t.prototype.translate=function(t,e){return this.tx+=t,this.ty+=e,this},t.prototype.scale=function(t,e){return this.a*=t,this.d*=e,this.c*=t,this.b*=e,this.tx*=t,this.ty*=e,this},t.prototype.rotate=function(t){var e=Math.cos(t),r=Math.sin(t),i=this.a,n=this.c,o=this.tx;return this.a=i*e-this.b*r,this.b=i*r+this.b*e,this.c=n*e-this.d*r,this.d=n*r+this.d*e,this.tx=o*e-this.ty*r,this.ty=o*r+this.ty*e,this},t.prototype.append=function(t){var e=this.a,r=this.b,i=this.c,n=this.d;return this.a=t.a*e+t.b*i,this.b=t.a*r+t.b*n,this.c=t.c*e+t.d*i,this.d=t.c*r+t.d*n,this.tx=t.tx*e+t.ty*i+this.tx,this.ty=t.tx*r+t.ty*n+this.ty,this},t.prototype.setTransform=function(t,e,r,i,n,o,s,a,h){return this.a=Math.cos(s+h)*n,this.b=Math.sin(s+h)*n,this.c=-Math.sin(s-a)*o,this.d=Math.cos(s-a)*o,this.tx=t-(r*this.a+i*this.c),this.ty=e-(r*this.b+i*this.d),this},t.prototype.prepend=function(t){var e=this.tx;if(1!==t.a||0!==t.b||0!==t.c||1!==t.d){var r=this.a,i=this.c;this.a=r*t.a+this.b*t.c,this.b=r*t.b+this.b*t.d,this.c=i*t.a+this.d*t.c,this.d=i*t.b+this.d*t.d}return this.tx=e*t.a+this.ty*t.c+t.tx,this.ty=e*t.b+this.ty*t.d+t.ty,this},t.prototype.decompose=function(t){var e=this.a,r=this.b,i=this.c,n=this.d,o=t.pivot,s=-Math.atan2(-i,n),a=Math.atan2(r,e),h=Math.abs(s+a);return h<1e-5||Math.abs(Me-h)<1e-5?(t.rotation=a,t.skew.x=t.skew.y=0):(t.rotation=0,t.skew.x=s,t.skew.y=a),t.scale.x=Math.sqrt(e*e+r*r),t.scale.y=Math.sqrt(i*i+n*n),t.position.x=this.tx+(o.x*e+o.y*i),t.position.y=this.ty+(o.x*r+o.y*n),t},t.prototype.invert=function(){var t=this.a,e=this.b,r=this.c,i=this.d,n=this.tx,o=t*i-e*r;return this.a=i/o,this.b=-e/o,this.c=-r/o,this.d=t/o,this.tx=(r*this.ty-i*n)/o,this.ty=-(t*this.ty-e*n)/o,this},t.prototype.identity=function(){return this.a=1,this.b=0,this.c=0,this.d=1,this.tx=0,this.ty=0,this},t.prototype.clone=function(){var e=new t;return e.a=this.a,e.b=this.b,e.c=this.c,e.d=this.d,e.tx=this.tx,e.ty=this.ty,e},t.prototype.copyTo=function(t){return t.a=this.a,t.b=this.b,t.c=this.c,t.d=this.d,t.tx=this.tx,t.ty=this.ty,t},t.prototype.copyFrom=function(t){return this.a=t.a,this.b=t.b,this.c=t.c,this.d=t.d,this.tx=t.tx,this.ty=t.ty,this},Object.defineProperty(t,"IDENTITY",{get:function(){return new t},enumerable:!1,configurable:!0}),Object.defineProperty(t,"TEMP_MATRIX",{get:function(){return new t},enumerable:!1,configurable:!0}),t}(),ke=[1,1,0,-1,-1,-1,0,1,1,1,0,-1,-1,-1,0,1],Xe=[0,1,1,1,0,-1,-1,-1,0,1,1,1,0,-1,-1,-1],je=[0,-1,-1,-1,0,1,1,1,0,1,1,1,0,-1,-1,-1],He=[1,1,0,-1,-1,-1,0,1,-1,-1,0,1,1,1,0,-1],Ye=[],Ve=[],ze=Math.sign;!function(){for(var t=0;t<16;t++){var e=[];Ye.push(e);for(var r=0;r<16;r++)for(var i=ze(ke[t]*ke[r]+je[t]*Xe[r]),n=ze(Xe[t]*ke[r]+He[t]*Xe[r]),o=ze(ke[t]*je[r]+je[t]*He[r]),s=ze(Xe[t]*je[r]+He[t]*He[r]),a=0;a<16;a++)if(ke[a]===i&&Xe[a]===n&&je[a]===o&&He[a]===s){e.push(a);break}}for(t=0;t<16;t++){var h=new Ue;h.set(ke[t],Xe[t],je[t],He[t],0,0),Ve.push(h)}}();var We={E:0,SE:1,S:2,SW:3,W:4,NW:5,N:6,NE:7,MIRROR_VERTICAL:8,MAIN_DIAGONAL:10,MIRROR_HORIZONTAL:12,REVERSE_DIAGONAL:14,uX:function(t){return ke[t]},uY:function(t){return Xe[t]},vX:function(t){return je[t]},vY:function(t){return He[t]},inv:function(t){return 8&t?15&t:7&-t},add:function(t,e){return Ye[t][e]},sub:function(t,e){return Ye[t][We.inv(e)]},rotate180:function(t){return 4^t},isVertical:function(t){return 2==(3&t)},byDirection:function(t,e){return 2*Math.abs(t)<=Math.abs(e)?e>=0?We.S:We.N:2*Math.abs(e)<=Math.abs(t)?t>0?We.E:We.W:e>0?t>0?We.SE:We.SW:t>0?We.NE:We.NW},matrixAppendRotationInv:function(t,e,r,i){void 0===r&&(r=0),void 0===i&&(i=0);var n=Ve[We.inv(e)];n.tx=r,n.ty=i,t.append(n)}},qe=function(){function t(){this.worldTransform=new Ue,this.localTransform=new Ue,this.position=new Ge(this.onChange,this,0,0),this.scale=new Ge(this.onChange,this,1,1),this.pivot=new Ge(this.onChange,this,0,0),this.skew=new Ge(this.updateSkew,this,0,0),this._rotation=0,this._cx=1,this._sx=0,this._cy=0,this._sy=1,this._localID=0,this._currentLocalID=0,this._worldID=0,this._parentID=0}return t.prototype.onChange=function(){this._localID++},t.prototype.updateSkew=function(){this._cx=Math.cos(this._rotation+this.skew.y),this._sx=Math.sin(this._rotation+this.skew.y),this._cy=-Math.sin(this._rotation-this.skew.x),this._sy=Math.cos(this._rotation-this.skew.x),this._localID++},t.prototype.updateLocalTransform=function(){var t=this.localTransform;this._localID!==this._currentLocalID&&(t.a=this._cx*this.scale.x,t.b=this._sx*this.scale.x,t.c=this._cy*this.scale.y,t.d=this._sy*this.scale.y,t.tx=this.position.x-(this.pivot.x*t.a+this.pivot.y*t.c),t.ty=this.position.y-(this.pivot.x*t.b+this.pivot.y*t.d),this._currentLocalID=this._localID,this._parentID=-1)},t.prototype.updateTransform=function(t){var e=this.localTransform;if(this._localID!==this._currentLocalID&&(e.a=this._cx*this.scale.x,e.b=this._sx*this.scale.x,e.c=this._cy*this.scale.y,e.d=this._sy*this.scale.y,e.tx=this.position.x-(this.pivot.x*e.a+this.pivot.y*e.c),e.ty=this.position.y-(this.pivot.x*e.b+this.pivot.y*e.d),this._currentLocalID=this._localID,this._parentID=-1),this._parentID!==t._worldID){var r=t.worldTransform,i=this.worldTransform;i.a=e.a*r.a+e.b*r.c,i.b=e.a*r.b+e.b*r.d,i.c=e.c*r.a+e.d*r.c,i.d=e.c*r.b+e.d*r.d,i.tx=e.tx*r.a+e.ty*r.c+r.tx,i.ty=e.tx*r.b+e.ty*r.d+r.ty,this._parentID=t._worldID,this._worldID++}},t.prototype.setFromMatrix=function(t){t.decompose(this),this._localID++},Object.defineProperty(t.prototype,"rotation",{get:function(){return this._rotation},set:function(t){this._rotation!==t&&(this._rotation=t,this.updateSkew())},enumerable:!1,configurable:!0}),t.IDENTITY=new t,t}();U.SORTABLE_CHILDREN=!1;var Ke=function(){function t(){this.minX=1/0,this.minY=1/0,this.maxX=-1/0,this.maxY=-1/0,this.rect=null,this.updateID=-1}return t.prototype.isEmpty=function(){return this.minX>this.maxX||this.minY>this.maxY},t.prototype.clear=function(){this.minX=1/0,this.minY=1/0,this.maxX=-1/0,this.maxY=-1/0},t.prototype.getRectangle=function(t){return this.minX>this.maxX||this.minY>this.maxY?Ce.EMPTY:((t=t||new Ce(0,0,1,1)).x=this.minX,t.y=this.minY,t.width=this.maxX-this.minX,t.height=this.maxY-this.minY,t)},t.prototype.addPoint=function(t){this.minX=Math.min(this.minX,t.x),this.maxX=Math.max(this.maxX,t.x),this.minY=Math.min(this.minY,t.y),this.maxY=Math.max(this.maxY,t.y)},t.prototype.addPointMatrix=function(t,e){var r=t.a,i=t.b,n=t.c,o=t.d,s=t.tx,a=t.ty,h=r*e.x+n*e.y+s,u=i*e.x+o*e.y+a;this.minX=Math.min(this.minX,h),this.maxX=Math.max(this.maxX,h),this.minY=Math.min(this.minY,u),this.maxY=Math.max(this.maxY,u)},t.prototype.addQuad=function(t){var e=this.minX,r=this.minY,i=this.maxX,n=this.maxY,o=t[0],s=t[1];e=oi?o:i,n=s>n?s:n,e=(o=t[2])i?o:i,n=s>n?s:n,e=(o=t[4])i?o:i,n=s>n?s:n,e=(o=t[6])i?o:i,n=s>n?s:n,this.minX=e,this.minY=r,this.maxX=i,this.maxY=n},t.prototype.addFrame=function(t,e,r,i,n){this.addFrameMatrix(t.worldTransform,e,r,i,n)},t.prototype.addFrameMatrix=function(t,e,r,i,n){var o=t.a,s=t.b,a=t.c,h=t.d,u=t.tx,l=t.ty,c=this.minX,d=this.minY,f=this.maxX,p=this.maxY,_=o*e+a*r+u,v=s*e+h*r+l;c=_f?_:f,p=v>p?v:p,c=(_=o*i+a*r+u)f?_:f,p=v>p?v:p,c=(_=o*e+a*n+u)f?_:f,p=v>p?v:p,c=(_=o*i+a*n+u)f?_:f,p=v>p?v:p,this.minX=c,this.minY=d,this.maxX=f,this.maxY=p},t.prototype.addVertexData=function(t,e,r){for(var i=this.minX,n=this.minY,o=this.maxX,s=this.maxY,a=e;ao?h:o,s=u>s?u:s}this.minX=i,this.minY=n,this.maxX=o,this.maxY=s},t.prototype.addVertices=function(t,e,r,i){this.addVerticesMatrix(t.worldTransform,e,r,i)},t.prototype.addVerticesMatrix=function(t,e,r,i,n,o){void 0===n&&(n=0),void 0===o&&(o=n);for(var s=t.a,a=t.b,h=t.c,u=t.d,l=t.tx,c=t.ty,d=this.minX,f=this.minY,p=this.maxX,_=this.maxY,v=r;vi?t.maxX:i,this.maxY=t.maxY>n?t.maxY:n},t.prototype.addBoundsMask=function(t,e){var r=t.minX>e.minX?t.minX:e.minX,i=t.minY>e.minY?t.minY:e.minY,n=t.maxXh?n:h,this.maxY=o>u?o:u}},t.prototype.addBoundsMatrix=function(t,e){this.addFrameMatrix(e,t.minX,t.minY,t.maxX,t.maxY)},t.prototype.addBoundsArea=function(t,e){var r=t.minX>e.x?t.minX:e.x,i=t.minY>e.y?t.minY:e.y,n=t.maxXh?n:h,this.maxY=o>u?o:u}},t.prototype.pad=function(t,e){void 0===t&&(t=0),void 0===e&&(e=t),this.isEmpty()||(this.minX-=t,this.maxX+=t,this.minY-=e,this.maxY+=e)},t.prototype.addFramePad=function(t,e,r,i,n,o){t-=n,e-=o,r+=n,i+=o,this.minX=this.minXr?this.maxX:r,this.minY=this.minYi?this.maxY:i},t}(),Ze=function(t,e){return Ze=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r])},Ze(t,e)};function Qe(t,e){function r(){this.constructor=t}Ze(t,e),t.prototype=null===e?Object.create(e):(r.prototype=e.prototype,new r)}var Je=function(t){function e(){var e=t.call(this)||this;return e.tempDisplayObjectParent=null,e.transform=new qe,e.alpha=1,e.visible=!0,e.renderable=!0,e.cullable=!1,e.cullArea=null,e.parent=null,e.worldAlpha=1,e._lastSortedIndex=0,e._zIndex=0,e.filterArea=null,e.filters=null,e._enabledFilters=null,e._bounds=new Ke,e._localBounds=null,e._boundsID=0,e._boundsRect=null,e._localBoundsRect=null,e._mask=null,e._maskRefCount=0,e._destroyed=!1,e.isSprite=!1,e.isMask=!1,e}return Qe(e,t),e.mixin=function(t){for(var r=Object.keys(t),i=0;i1)for(var i=0;ithis.children.length)throw new Error(t+"addChildAt: The index "+e+" supplied is out of bounds "+this.children.length);return t.parent&&t.parent.removeChild(t),t.parent=this,this.sortDirty=!0,t.transform._parentID=-1,this.children.splice(e,0,t),this._boundsID++,this.onChildrenChange(e),t.emit("added",this),this.emit("childAdded",t,this,e),t},r.prototype.swapChildren=function(t,e){if(t!==e){var r=this.getChildIndex(t),i=this.getChildIndex(e);this.children[r]=e,this.children[i]=t,this.onChildrenChange(r=this.children.length)throw new Error("The index "+e+" supplied is out of bounds "+this.children.length);var r=this.getChildIndex(t);fe(this.children,r,1),this.children.splice(e,0,t),this.onChildrenChange(e)},r.prototype.getChildAt=function(t){if(t<0||t>=this.children.length)throw new Error("getChildAt: Index ("+t+") does not exist.");return this.children[t]},r.prototype.removeChild=function(){for(var t=arguments,e=[],r=0;r1)for(var i=0;i0&&n<=e){r=this.children.splice(i,n);for(var o=0;o1&&this.children.sort(tr),this.sortDirty=!1},r.prototype.updateTransform=function(){this.sortableChildren&&this.sortDirty&&this.sortChildren(),this._boundsID++,this.transform.updateTransform(this.parent.transform),this.worldAlpha=this.alpha*this.parent.worldAlpha;for(var t=0,e=this.children.length;t0&&e.height>0){var i,n;if(this.cullArea?(i=this.cullArea,n=this.worldTransform):this._render!==r.prototype._render&&(i=this.getBounds(!0)),i&&e.intersects(i,n))this._render(t);else if(this.cullArea)return;for(var o=0,s=this.children.length;o8)throw new Error("max arguments reached");var h=this,u=h.name,l=h.items;this._aliasCount++;for(var c=0,d=l.length;c0&&this.items.length>1&&(this._aliasCount=0,this.items=this.items.slice(0))},t.prototype.add=function(t){return t[this._name]&&(this.ensureNonAliasedItems(),this.remove(t),this.items.push(t)),this},t.prototype.remove=function(t){var e=this.items.indexOf(t);return-1!==e&&(this.ensureNonAliasedItems(),this.items.splice(e,1)),this},t.prototype.contains=function(t){return-1!==this.items.indexOf(t)},t.prototype.removeAll=function(){return this.ensureNonAliasedItems(),this.items.length=0,this},t.prototype.destroy=function(){this.removeAll(),this.items=null,this._name=null},Object.defineProperty(t.prototype,"empty",{get:function(){return 0===this.items.length},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"name",{get:function(){return this._name},enumerable:!1,configurable:!0}),t}();Object.defineProperties(or.prototype,{dispatch:{value:or.prototype.emit},run:{value:or.prototype.emit}}),t.UPDATE_PRIORITY=void 0,U.TARGET_FPMS=.06,function(t){t[t.INTERACTION=50]="INTERACTION",t[t.HIGH=25]="HIGH",t[t.NORMAL=0]="NORMAL",t[t.LOW=-25]="LOW",t[t.UTILITY=-50]="UTILITY"}(t.UPDATE_PRIORITY||(t.UPDATE_PRIORITY={}));var sr=function(){function t(t,e,r,i){void 0===e&&(e=null),void 0===r&&(r=0),void 0===i&&(i=!1),this.next=null,this.previous=null,this._destroyed=!1,this.fn=t,this.context=e,this.priority=r,this.once=i}return t.prototype.match=function(t,e){return void 0===e&&(e=null),this.fn===t&&this.context===e},t.prototype.emit=function(t){this.fn&&(this.context?this.fn.call(this.context,t):this.fn(t));var e=this.next;return this.once&&this.destroy(!0),this._destroyed&&(this.next=null),e},t.prototype.connect=function(t){this.previous=t,t.next&&(t.next.previous=this),this.next=t.next,t.next=this},t.prototype.destroy=function(t){void 0===t&&(t=!1),this._destroyed=!0,this.fn=null,this.context=null,this.previous&&(this.previous.next=this.next),this.next&&(this.next.previous=this.previous);var e=this.next;return this.next=t?null:e,this.previous=null,e},t}(),ar=function(){function e(){var t=this;this.autoStart=!1,this.deltaTime=1,this.lastTime=-1,this.speed=1,this.started=!1,this._requestId=null,this._maxElapsedMS=100,this._minElapsedMS=0,this._protected=!1,this._lastFrame=-1,this._head=new sr(null,null,1/0),this.deltaMS=1/U.TARGET_FPMS,this.elapsedMS=1/U.TARGET_FPMS,this._tick=function(e){t._requestId=null,t.started&&(t.update(e),t.started&&null===t._requestId&&t._head.next&&(t._requestId=requestAnimationFrame(t._tick)))}}return e.prototype._requestIfNeeded=function(){null===this._requestId&&this._head.next&&(this.lastTime=performance.now(),this._lastFrame=this.lastTime,this._requestId=requestAnimationFrame(this._tick))},e.prototype._cancelIfNeeded=function(){null!==this._requestId&&(cancelAnimationFrame(this._requestId),this._requestId=null)},e.prototype._startIfPossible=function(){this.started?this._requestIfNeeded():this.autoStart&&this.start()},e.prototype.add=function(e,r,i){return void 0===i&&(i=t.UPDATE_PRIORITY.NORMAL),this._addListener(new sr(e,r,i))},e.prototype.addOnce=function(e,r,i){return void 0===i&&(i=t.UPDATE_PRIORITY.NORMAL),this._addListener(new sr(e,r,i,!0))},e.prototype._addListener=function(t){var e=this._head.next,r=this._head;if(e){for(;e;){if(t.priority>e.priority){t.connect(r);break}r=e,e=e.next}t.previous||t.connect(r)}else t.connect(r);return this._startIfPossible(),this},e.prototype.remove=function(t,e){for(var r=this._head.next;r;)r=r.match(t,e)?r.destroy():r.next;return this._head.next||this._cancelIfNeeded(),this},Object.defineProperty(e.prototype,"count",{get:function(){if(!this._head)return 0;for(var t=0,e=this._head;e=e.next;)t++;return t},enumerable:!1,configurable:!0}),e.prototype.start=function(){this.started||(this.started=!0,this._requestIfNeeded())},e.prototype.stop=function(){this.started&&(this.started=!1,this._cancelIfNeeded())},e.prototype.destroy=function(){if(!this._protected){this.stop();for(var t=this._head.next;t;)t=t.destroy(!0);this._head.destroy(),this._head=null}},e.prototype.update=function(t){var e;if(void 0===t&&(t=performance.now()),t>this.lastTime){if((e=this.elapsedMS=t-this.lastTime)>this._maxElapsedMS&&(e=this._maxElapsedMS),e*=this.speed,this._minElapsedMS){var r=t-this._lastFrame|0;if(r=0;--n){var o=ur[n];if(o.test&&o.test(t,r))return new o(t,e)}throw new Error("Unrecognized source type to auto-detect Resource")}var cr=function(t,e){return cr=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r])},cr(t,e)};function dr(t,e){function r(){this.constructor=t}cr(t,e),t.prototype=null===e?Object.create(e):(r.prototype=e.prototype,new r)}var fr=function(){return fr=Object.assign||function(t){for(var e,r=arguments,i=1,n=arguments.length;i0&&l>0,n.textureCacheIds=[],n.destroyed=!1,n.resource=null,n._batchEnabled=0,n._batchLocation=0,n.parentTextureArray=null,n.setResource(r),n}return dr(r,e),Object.defineProperty(r.prototype,"realWidth",{get:function(){return Math.round(this.width*this.resolution)},enumerable:!1,configurable:!0}),Object.defineProperty(r.prototype,"realHeight",{get:function(){return Math.round(this.height*this.resolution)},enumerable:!1,configurable:!0}),Object.defineProperty(r.prototype,"mipmap",{get:function(){return this._mipmap},set:function(t){this._mipmap!==t&&(this._mipmap=t,this.dirtyStyleId++)},enumerable:!1,configurable:!0}),Object.defineProperty(r.prototype,"scaleMode",{get:function(){return this._scaleMode},set:function(t){this._scaleMode!==t&&(this._scaleMode=t,this.dirtyStyleId++)},enumerable:!1,configurable:!0}),Object.defineProperty(r.prototype,"wrapMode",{get:function(){return this._wrapMode},set:function(t){this._wrapMode!==t&&(this._wrapMode=t,this.dirtyStyleId++)},enumerable:!1,configurable:!0}),r.prototype.setStyle=function(t,e){var r;return void 0!==t&&t!==this.scaleMode&&(this.scaleMode=t,r=!0),void 0!==e&&e!==this.mipmap&&(this.mipmap=e,r=!0),r&&this.dirtyStyleId++,this},r.prototype.setSize=function(t,e,r){return r=r||this.resolution,this.setRealSize(t*r,e*r,r)},r.prototype.setRealSize=function(t,e,r){return this.resolution=r||this.resolution,this.width=Math.round(t)/this.resolution,this.height=Math.round(e)/this.resolution,this._refreshPOT(),this.update(),this},r.prototype._refreshPOT=function(){this.isPowerOfTwo=ce(this.realWidth)&&ce(this.realHeight)},r.prototype.setResolution=function(t){var e=this.resolution;return e===t||(this.resolution=t,this.valid&&(this.width=Math.round(this.width*e)/t,this.height=Math.round(this.height*e)/t,this.emit("update",this)),this._refreshPOT()),this},r.prototype.setResource=function(t){if(this.resource===t)return this;if(this.resource)throw new Error("Resource can be set only once");return t.bind(this),this.resource=t,this},r.prototype.update=function(){this.valid?(this.dirtyId++,this.dirtyStyleId++,this.emit("update",this)):this.width>0&&this.height>0&&(this.valid=!0,this.emit("loaded",this),this.emit("update",this))},r.prototype.onError=function(t){this.emit("error",this,t)},r.prototype.destroy=function(){this.resource&&(this.resource.unbind(this),this.resource.internal&&this.resource.destroy(),this.resource=null),this.cacheId&&(delete Te[this.cacheId],delete ge[this.cacheId],this.cacheId=null),this.dispose(),r.removeFromCache(this),this.textureCacheIds=null,this.destroyed=!0},r.prototype.dispose=function(){this.emit("dispose",this)},r.prototype.castToBaseTexture=function(){return this},r.from=function(t,e,i){void 0===i&&(i=U.STRICT_TEXTURE_CACHE);var n="string"==typeof t,o=null;if(n)o=t;else{if(!t._pixiId){var s=e&&e.pixiIdPrefix||"pixiid";t._pixiId=s+"_"+ve()}o=t._pixiId}var a=Te[o];if(n&&i&&!a)throw new Error('The cacheId "'+o+'" does not exist in BaseTextureCache.');return a||((a=new r(t,e)).cacheId=o,r.addToCache(a,o)),a},r.fromBuffer=function(e,i,n,o){e=e||new Float32Array(i*n*4);var s=new _r(e,{width:i,height:n}),a=e instanceof Float32Array?t.TYPES.FLOAT:t.TYPES.UNSIGNED_BYTE;return new r(s,Object.assign({},vr,o||{width:i,height:n,type:a}))},r.addToCache=function(t,e){e&&(-1===t.textureCacheIds.indexOf(e)&&t.textureCacheIds.push(e),Te[e]&&console.warn("BaseTexture added to the cache with an id ["+e+"] that already had an entry"),Te[e]=t)},r.removeFromCache=function(t){if("string"==typeof t){var e=Te[t];if(e){var r=e.textureCacheIds.indexOf(t);return r>-1&&e.textureCacheIds.splice(r,1),delete Te[t],e}}else if(t&&t.textureCacheIds){for(var i=0;i0){if(!e.resource)throw new Error("CubeResource does not support copying of renderTexture.");this.addResourceAt(e.resource,r)}else e.target=t.TARGETS.TEXTURE_CUBE_MAP_POSITIVE_X+r,e.parentTextureArray=this.baseTexture,this.items[r]=e;return e.valid&&!this.valid&&this.resize(e.realWidth,e.realHeight),this.items[r]=e,this},r.prototype.upload=function(t,e,i){for(var n=this.itemDirtyIds,o=0;o)?\s*()]*-->)?\s*\]*(?:\s(width|height)=('|")(\d*(?:\.\d+)?)(?:px)?('|"))[^>]*(?:\s(width|height)=('|")(\d*(?:\.\d+)?)(?:px)?('|"))[^>]*>/i,e}(Tr),Sr=function(t){function e(r,i){var n=this;if(i=i||{},!(r instanceof HTMLVideoElement)){var o=document.createElement("video");o.setAttribute("preload","auto"),o.setAttribute("webkit-playsinline",""),o.setAttribute("playsinline",""),"string"==typeof r&&(r=[r]);var s=r[0].src||r[0];Tr.crossOrigin(o,s,i.crossorigin);for(var a=0;a2},e.prototype._onPlayStart=function(){this.valid||this._onCanPlay(),this.autoUpdate&&!this._isConnectedToTicker&&(ar.shared.add(this.update,this),this._isConnectedToTicker=!0)},e.prototype._onPlayStop=function(){this._isConnectedToTicker&&(ar.shared.remove(this.update,this),this._isConnectedToTicker=!1)},e.prototype._onCanPlay=function(){var t=this.source;t.removeEventListener("canplay",this._onCanPlay),t.removeEventListener("canplaythrough",this._onCanPlay);var e=this.valid;this.resize(t.videoWidth,t.videoHeight),!e&&this._resolve&&(this._resolve(this),this._resolve=null),this._isSourcePlaying()?this._onPlayStart():this.autoPlay&&t.play()},e.prototype.dispose=function(){this._isConnectedToTicker&&(ar.shared.remove(this.update,this),this._isConnectedToTicker=!1);var e=this.source;e&&(e.removeEventListener("error",this._onError,!0),e.pause(),e.src="",e.load()),t.prototype.dispose.call(this)},Object.defineProperty(e.prototype,"autoUpdate",{get:function(){return this._autoUpdate},set:function(t){t!==this._autoUpdate&&(this._autoUpdate=t,!this._autoUpdate&&this._isConnectedToTicker?(ar.shared.remove(this.update,this),this._isConnectedToTicker=!1):this._autoUpdate&&!this._isConnectedToTicker&&this._isSourcePlaying()&&(ar.shared.add(this.update,this),this._isConnectedToTicker=!0))},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"updateFPS",{get:function(){return this._updateFPS},set:function(t){t!==this._updateFPS&&(this._updateFPS=t)},enumerable:!1,configurable:!0}),e.test=function(t,r){return globalThis.HTMLVideoElement&&t instanceof HTMLVideoElement||e.TYPES.indexOf(r)>-1},e.TYPES=["mp4","m4v","webm","ogg","ogv","h264","avi","mov"],e.MIME_TYPES={ogv:"video/ogg",mov:"video/quicktime",m4v:"video/mp4"},e}(Tr),Rr=function(t){function e(e){return t.call(this,e)||this}return dr(e,t),e.test=function(t){return!!globalThis.createImageBitmap&&"undefined"!=typeof ImageBitmap&&t instanceof ImageBitmap},e}(Tr);ur.push(xr,Rr,Er,Sr,Ar,_r,br,gr);var Or={__proto__:null,Resource:pr,BaseImageResource:Tr,INSTALLED:ur,autoDetectResource:lr,AbstractMultiResource:yr,ArrayResource:gr,BufferResource:_r,CanvasResource:Er,CubeResource:br,ImageResource:xr,SVGResource:Ar,VideoResource:Sr,ImageBitmapResource:Rr},Mr=function(e){function r(){return null!==e&&e.apply(this,arguments)||this}return dr(r,e),r.prototype.upload=function(e,r,i){var n=e.gl;n.pixelStorei(n.UNPACK_PREMULTIPLY_ALPHA_WEBGL,r.alphaMode===t.ALPHA_MODES.UNPACK);var o=r.realWidth,s=r.realHeight;return i.width===o&&i.height===s?n.texSubImage2D(r.target,0,0,0,o,s,r.format,i.type,this.data):(i.width=o,i.height=s,n.texImage2D(r.target,0,i.internalFormat,o,s,0,r.format,i.type,this.data)),!0},r}(_r),Pr=function(){function e(e,r){this.width=Math.round(e||100),this.height=Math.round(r||100),this.stencil=!1,this.depth=!1,this.dirtyId=0,this.dirtyFormat=0,this.dirtySize=0,this.depthTexture=null,this.colorTextures=[],this.glFramebuffers={},this.disposeRunner=new or("disposeFramebuffer"),this.multisample=t.MSAA_QUALITY.NONE}return Object.defineProperty(e.prototype,"colorTexture",{get:function(){return this.colorTextures[0]},enumerable:!1,configurable:!0}),e.prototype.addColorTexture=function(e,r){return void 0===e&&(e=0),this.colorTextures[e]=r||new mr(null,{scaleMode:t.SCALE_MODES.NEAREST,resolution:1,mipmap:t.MIPMAP_MODES.OFF,width:this.width,height:this.height}),this.dirtyId++,this.dirtyFormat++,this},e.prototype.addDepthTexture=function(e){return this.depthTexture=e||new mr(new Mr(null,{width:this.width,height:this.height}),{scaleMode:t.SCALE_MODES.NEAREST,resolution:1,width:this.width,height:this.height,mipmap:t.MIPMAP_MODES.OFF,format:t.FORMATS.DEPTH_COMPONENT,type:t.TYPES.UNSIGNED_SHORT}),this.dirtyId++,this.dirtyFormat++,this},e.prototype.enableDepth=function(){return this.depth=!0,this.dirtyId++,this.dirtyFormat++,this},e.prototype.enableStencil=function(){return this.stencil=!0,this.dirtyId++,this.dirtyFormat++,this},e.prototype.resize=function(t,e){if(t=Math.round(t),e=Math.round(e),t!==this.width||e!==this.height){this.width=t,this.height=e,this.dirtyId++,this.dirtySize++;for(var r=0;r-1&&e.textureCacheIds.splice(r,1),delete ge[t],e}}else if(t&&t.textureCacheIds){for(var i=0;ithis.baseTexture.width,s=r+n>this.baseTexture.height;if(o||s){var a=o&&s?"and":"or",h="X: "+e+" + "+i+" = "+(e+i)+" > "+this.baseTexture.width,u="Y: "+r+" + "+n+" = "+(r+n)+" > "+this.baseTexture.height;throw new Error("Texture Error: frame does not fit inside the base Texture dimensions: "+h+" "+a+" "+u)}this.valid=i&&n&&this.baseTexture.valid,this.trim||this.rotate||(this.orig=t),this.valid&&this.updateUvs()},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"rotate",{get:function(){return this._rotate},set:function(t){this._rotate=t,this.valid&&this.updateUvs()},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"width",{get:function(){return this.orig.width},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"height",{get:function(){return this.orig.height},enumerable:!1,configurable:!0}),e.prototype.castToBaseTexture=function(){return this.baseTexture},Object.defineProperty(e,"EMPTY",{get:function(){return e._EMPTY||(e._EMPTY=new e(new mr),Cr(e._EMPTY),Cr(e._EMPTY.baseTexture)),e._EMPTY},enumerable:!1,configurable:!0}),Object.defineProperty(e,"WHITE",{get:function(){if(!e._WHITE){var t=U.ADAPTER.createCanvas(16,16),r=t.getContext("2d");t.width=16,t.height=16,r.fillStyle="white",r.fillRect(0,0,16,16),e._WHITE=new e(mr.from(t)),Cr(e._WHITE),Cr(e._WHITE.baseTexture)}return e._WHITE},enumerable:!1,configurable:!0}),e}(j),Fr=function(t){function e(e,r){var i=t.call(this,e,r)||this;return i.valid=!0,i.filterFrame=null,i.filterPoolKey=null,i.updateUvs(),i}return dr(e,t),Object.defineProperty(e.prototype,"framebuffer",{get:function(){return this.baseTexture.framebuffer},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"multisample",{get:function(){return this.framebuffer.multisample},set:function(t){this.framebuffer.multisample=t},enumerable:!1,configurable:!0}),e.prototype.resize=function(t,e,r){void 0===r&&(r=!0);var i=this.baseTexture.resolution,n=Math.round(t*i)/i,o=Math.round(e*i)/i;this.valid=n>0&&o>0,this._frame.width=this.orig.width=n,this._frame.height=this.orig.height=o,r&&this.baseTexture.resize(n,o),this.updateUvs()},e.prototype.setResolution=function(t){var e=this.baseTexture;e.resolution!==t&&(e.setResolution(t),this.resize(e.width,e.height,!1))},e.create=function(t){for(var r=arguments,i=[],n=1;n1?-n:-1:(o=((65535&(e=le(e)))<<16|65535&(r=le(r)))>>>0,n>1&&(o+=4294967296*n)),this.texturePool[o]||(this.texturePool[o]=[]);var s=this.texturePool[o].pop();return s||(s=this.createTexture(e,r,n)),s.filterPoolKey=o,s.setResolution(i),s},e.prototype.getFilterTexture=function(e,r,i){var n=this.getOptimalTexture(e.width,e.height,r||e.resolution,i||t.MSAA_QUALITY.NONE);return n.filterFrame=e.filterFrame,n},e.prototype.returnTexture=function(t){var e=t.filterPoolKey;t.filterFrame=null,this.texturePool[e].push(t)},e.prototype.returnFilterTexture=function(t){this.returnTexture(t)},e.prototype.clear=function(t){if(t=!1!==t)for(var e in this.texturePool){var r=this.texturePool[e];if(r)for(var i=0;i0&&t.height>0,this.texturePool)if(Number(e)<0){var r=this.texturePool[e];if(r)for(var i=0;i1){for(var u=0;u1&&((c=this.getOptimalFilterTexture(l.width,l.height,r.resolution)).filterFrame=l.filterFrame),i[d].apply(this,l,c,t.CLEAR_MODES.CLEAR,r);var f=l;l=c,c=f}i[d].apply(this,l,u.renderTexture,t.CLEAR_MODES.BLEND,r),d>1&&r.multisample>1&&this.returnFilterTexture(r.renderTexture),this.returnFilterTexture(l),this.returnFilterTexture(c)}r.clear(),this.statePool.push(r)},e.prototype.bindAndClear=function(e,r){void 0===r&&(r=t.CLEAR_MODES.CLEAR);var i=this.renderer,n=i.renderTexture,o=i.state;if(e===this.defaultFilterStack[this.defaultFilterStack.length-1].renderTexture?this.renderer.projection.transform=this.activeState.transform:this.renderer.projection.transform=null,e&&e.filterFrame){var s=this.tempRect;s.x=0,s.y=0,s.width=e.filterFrame.width,s.height=e.filterFrame.height,n.bind(e,e.filterFrame,s)}else e!==this.defaultFilterStack[this.defaultFilterStack.length-1].renderTexture?n.bind(e):this.renderer.renderTexture.bind(e,this.activeState.bindingSourceFrame,this.activeState.bindingDestinationFrame);var a=1&o.stateId||this.forceClear;(r===t.CLEAR_MODES.CLEAR||r===t.CLEAR_MODES.BLIT&&a)&&this.renderer.framebuffer.clear(0,0,0,0)},e.prototype.applyFilter=function(e,r,i,n){var o=this.renderer;o.state.set(e.state),this.bindAndClear(i,n),e.uniforms.uSampler=r,e.uniforms.filterGlobals=this.globalUniforms,o.shader.bind(e),e.legacy=!!e.program.attributeData.aTextureCoord,e.legacy?(this.quadUv.map(r._frame,r.filterFrame),o.geometry.bind(this.quadUv),o.geometry.draw(t.DRAW_MODES.TRIANGLES)):(o.geometry.bind(this.quad),o.geometry.draw(t.DRAW_MODES.TRIANGLE_STRIP))},e.prototype.calculateSpriteMatrix=function(t,e){var r=this.activeState,i=r.sourceFrame,n=r.destinationFrame,o=e._texture.orig,s=t.set(n.width,0,0,n.height,i.x,i.y),a=e.worldTransform.copyTo(Ue.TEMP_MATRIX);return a.invert(),s.prepend(a),s.scale(1/o.width,1/o.height),s.translate(e.anchor.x,e.anchor.y),s},e.prototype.destroy=function(){this.renderer=null,this.texturePool.clear(!1)},e.prototype.getOptimalFilterTexture=function(e,r,i,n){return void 0===i&&(i=1),void 0===n&&(n=t.MSAA_QUALITY.NONE),this.texturePool.getOptimalTexture(e,r,i,n)},e.prototype.getFilterTexture=function(e,r,i){if("number"==typeof e){var n=e;e=r,r=n}e=e||this.activeState.renderTexture;var o=this.texturePool.getOptimalTexture(e.width,e.height,r||e.resolution,i||t.MSAA_QUALITY.NONE);return o.filterFrame=e.filterFrame,o},e.prototype.returnFilterTexture=function(t){this.texturePool.returnTexture(t)},e.prototype.emptyPool=function(){this.texturePool.clear(!0)},e.prototype.resize=function(){this.texturePool.setScreenSize(this.renderer.view)},e.prototype.transformAABB=function(t,e){var r=Zr[0],i=Zr[1],n=Zr[2],o=Zr[3];r.set(e.left,e.top),i.set(e.left,e.bottom),n.set(e.right,e.top),o.set(e.right,e.bottom),t.apply(r,r),t.apply(i,i),t.apply(n,n),t.apply(o,o);var s=Math.min(r.x,i.x,n.x,o.x),a=Math.min(r.y,i.y,n.y,o.y),h=Math.max(r.x,i.x,n.x,o.x),u=Math.max(r.y,i.y,n.y,o.y);e.x=s,e.y=a,e.width=h-s,e.height=u-a},e.prototype.roundFrame=function(t,e,r,i,n){if(!(t.width<=0||t.height<=0||r.width<=0||r.height<=0)){if(n){var o=n.a,s=n.b,a=n.c,h=n.d;if((Math.abs(s)>1e-4||Math.abs(a)>1e-4)&&(Math.abs(o)>1e-4||Math.abs(h)>1e-4))return}(n=n?Qr.copyFrom(n):Qr.identity()).translate(-r.x,-r.y).scale(i.width/r.width,i.height/r.height).translate(i.x,i.y),this.transformAABB(n,t),t.ceil(e),this.transformAABB(n.invert(),t)}},e}(),$r=function(){function t(t){this.renderer=t}return t.prototype.flush=function(){},t.prototype.destroy=function(){this.renderer=null},t.prototype.start=function(){},t.prototype.stop=function(){this.flush()},t.prototype.render=function(t){},t}(),ti=function(){function t(t){this.renderer=t,this.emptyRenderer=new $r(t),this.currentRenderer=this.emptyRenderer}return t.prototype.setObjectRenderer=function(t){this.currentRenderer!==t&&(this.currentRenderer.stop(),this.currentRenderer=t,this.currentRenderer.start())},t.prototype.flush=function(){this.setObjectRenderer(this.emptyRenderer)},t.prototype.reset=function(){this.setObjectRenderer(this.emptyRenderer)},t.prototype.copyBoundTextures=function(t,e){for(var r=this.renderer.texture.boundTextures,i=e-1;i>=0;--i)t[i]=r[i]||null,t[i]&&(t[i]._batchLocation=i)},t.prototype.boundArray=function(t,e,r,i){for(var n=t.elements,o=t.ids,s=t.count,a=0,h=0;h=0&&l=t.ENV.WEBGL2&&(i=e.getContext("webgl2",r)),i)this.webGLVersion=2;else if(this.webGLVersion=1,!(i=e.getContext("webgl",r)||e.getContext("experimental-webgl",r)))throw new Error("This browser does not support WebGL. Try using the canvas renderer");return this.gl=i,this.getExtensions(),this.gl},e.prototype.getExtensions=function(){var t=this.gl,e={loseContext:t.getExtension("WEBGL_lose_context"),anisotropicFiltering:t.getExtension("EXT_texture_filter_anisotropic"),floatTextureLinear:t.getExtension("OES_texture_float_linear"),s3tc:t.getExtension("WEBGL_compressed_texture_s3tc"),s3tc_sRGB:t.getExtension("WEBGL_compressed_texture_s3tc_srgb"),etc:t.getExtension("WEBGL_compressed_texture_etc"),etc1:t.getExtension("WEBGL_compressed_texture_etc1"),pvrtc:t.getExtension("WEBGL_compressed_texture_pvrtc")||t.getExtension("WEBKIT_WEBGL_compressed_texture_pvrtc"),atc:t.getExtension("WEBGL_compressed_texture_atc"),astc:t.getExtension("WEBGL_compressed_texture_astc")};1===this.webGLVersion?Object.assign(this.extensions,e,{drawBuffers:t.getExtension("WEBGL_draw_buffers"),depthTexture:t.getExtension("WEBGL_depth_texture"),vertexArrayObject:t.getExtension("OES_vertex_array_object")||t.getExtension("MOZ_OES_vertex_array_object")||t.getExtension("WEBKIT_OES_vertex_array_object"),uint32ElementIndex:t.getExtension("OES_element_index_uint"),floatTexture:t.getExtension("OES_texture_float"),floatTextureLinear:t.getExtension("OES_texture_float_linear"),textureHalfFloat:t.getExtension("OES_texture_half_float"),textureHalfFloatLinear:t.getExtension("OES_texture_half_float_linear")}):2===this.webGLVersion&&Object.assign(this.extensions,e,{colorBufferFloat:t.getExtension("EXT_color_buffer_float")})},e.prototype.handleContextLost=function(t){var e=this;t.preventDefault(),setTimeout((function(){e.gl.isContextLost()&&e.extensions.loseContext&&e.extensions.loseContext.restoreContext()}),0)},e.prototype.handleContextRestored=function(){this.renderer.runners.contextChange.emit(this.gl)},e.prototype.destroy=function(){var t=this.renderer.view;this.renderer=null,t.removeEventListener("webglcontextlost",this.handleContextLost),t.removeEventListener("webglcontextrestored",this.handleContextRestored),this.gl.useProgram(null),this.extensions.loseContext&&this.extensions.loseContext.loseContext()},e.prototype.postrender=function(){this.renderer.renderingToScreen&&this.gl.flush()},e.prototype.validateContext=function(t){var e=t.getContextAttributes(),r="WebGL2RenderingContext"in globalThis&&t instanceof globalThis.WebGL2RenderingContext;r&&(this.webGLVersion=2),e&&!e.stencil&&console.warn("Provided WebGL context does not have a stencil buffer, masks may not render correctly");var i=r||!!t.getExtension("OES_element_index_uint");this.supports.uint32Indices=i,i||console.warn("Provided WebGL context does not support 32 index buffer, complex graphics may not render correctly")},e}(),ii=function(e){this.framebuffer=e,this.stencil=null,this.dirtyId=-1,this.dirtyFormat=-1,this.dirtySize=-1,this.multisample=t.MSAA_QUALITY.NONE,this.msaaBuffer=null,this.blitFramebuffer=null,this.mipLevel=0},ni=new Ce,oi=function(){function e(t){this.renderer=t,this.managedFramebuffers=[],this.unknownFramebuffer=new Pr(10,10),this.msaaSamples=null}return e.prototype.contextChange=function(){this.disposeAll(!0);var e=this.gl=this.renderer.gl;if(this.CONTEXT_UID=this.renderer.CONTEXT_UID,this.current=this.unknownFramebuffer,this.viewport=new Ce,this.hasMRT=!0,this.writeDepthTexture=!0,1===this.renderer.context.webGLVersion){var r=this.renderer.context.extensions.drawBuffers,i=this.renderer.context.extensions.depthTexture;U.PREFER_ENV===t.ENV.WEBGL_LEGACY&&(r=null,i=null),r?e.drawBuffers=function(t){return r.drawBuffersWEBGL(t)}:(this.hasMRT=!1,e.drawBuffers=function(){}),i||(this.writeDepthTexture=!1)}else this.msaaSamples=e.getInternalformatParameter(e.RENDERBUFFER,e.RGBA8,e.SAMPLES)},e.prototype.bind=function(t,e,r){void 0===r&&(r=0);var i=this.gl;if(t){var n=t.glFramebuffers[this.CONTEXT_UID]||this.initFramebuffer(t);this.current!==t&&(this.current=t,i.bindFramebuffer(i.FRAMEBUFFER,n.framebuffer)),n.mipLevel!==r&&(t.dirtyId++,t.dirtyFormat++,n.mipLevel=r),n.dirtyId!==t.dirtyId&&(n.dirtyId=t.dirtyId,n.dirtyFormat!==t.dirtyFormat?(n.dirtyFormat=t.dirtyFormat,n.dirtySize=t.dirtySize,this.updateFramebuffer(t,r)):n.dirtySize!==t.dirtySize&&(n.dirtySize=t.dirtySize,this.resizeFramebuffer(t)));for(var o=0;o>r,h=e.height>>r,u=a/e.width;this.setViewport(e.x*u,e.y*u,a,h)}else a=t.width>>r,h=t.height>>r,this.setViewport(0,0,a,h)}else this.current&&(this.current=null,i.bindFramebuffer(i.FRAMEBUFFER,null)),e?this.setViewport(e.x,e.y,e.width,e.height):this.setViewport(0,0,this.renderer.width,this.renderer.height)},e.prototype.setViewport=function(t,e,r,i){var n=this.viewport;t=Math.round(t),e=Math.round(e),r=Math.round(r),i=Math.round(i),n.width===r&&n.height===i&&n.x===t&&n.y===e||(n.x=t,n.y=e,n.width=r,n.height=i,this.gl.viewport(t,e,r,i))},Object.defineProperty(e.prototype,"size",{get:function(){return this.current?{x:0,y:0,width:this.current.width,height:this.current.height}:{x:0,y:0,width:this.renderer.width,height:this.renderer.height}},enumerable:!1,configurable:!0}),e.prototype.clear=function(e,r,i,n,o){void 0===o&&(o=t.BUFFER_BITS.COLOR|t.BUFFER_BITS.DEPTH);var s=this.gl;s.clearColor(e,r,i,n),s.clear(o)},e.prototype.initFramebuffer=function(t){var e=this.gl,r=new ii(e.createFramebuffer());return r.multisample=this.detectSamples(t.multisample),t.glFramebuffers[this.CONTEXT_UID]=r,this.managedFramebuffers.push(t),t.disposeRunner.add(this),r},e.prototype.resizeFramebuffer=function(t){var e=this.gl,r=t.glFramebuffers[this.CONTEXT_UID];r.msaaBuffer&&(e.bindRenderbuffer(e.RENDERBUFFER,r.msaaBuffer),e.renderbufferStorageMultisample(e.RENDERBUFFER,r.multisample,e.RGBA8,t.width,t.height)),r.stencil&&(e.bindRenderbuffer(e.RENDERBUFFER,r.stencil),r.msaaBuffer?e.renderbufferStorageMultisample(e.RENDERBUFFER,r.multisample,e.DEPTH24_STENCIL8,t.width,t.height):e.renderbufferStorage(e.RENDERBUFFER,e.DEPTH_STENCIL,t.width,t.height));var i=t.colorTextures,n=i.length;e.drawBuffers||(n=Math.min(n,1));for(var o=0;o1&&this.canMultisampleFramebuffer(t)?(i.msaaBuffer=i.msaaBuffer||r.createRenderbuffer(),r.bindRenderbuffer(r.RENDERBUFFER,i.msaaBuffer),r.renderbufferStorageMultisample(r.RENDERBUFFER,i.multisample,r.RGBA8,t.width,t.height),r.framebufferRenderbuffer(r.FRAMEBUFFER,r.COLOR_ATTACHMENT0,r.RENDERBUFFER,i.msaaBuffer)):i.msaaBuffer&&(r.deleteRenderbuffer(i.msaaBuffer),i.msaaBuffer=null,i.blitFramebuffer&&(i.blitFramebuffer.dispose(),i.blitFramebuffer=null));for(var s=[],a=0;a1&&r.drawBuffers(s),t.depthTexture&&this.writeDepthTexture){var l=t.depthTexture;this.renderer.texture.bind(l,0),r.framebufferTexture2D(r.FRAMEBUFFER,r.DEPTH_ATTACHMENT,r.TEXTURE_2D,l._glTextures[this.CONTEXT_UID].texture,e)}!t.stencil&&!t.depth||t.depthTexture&&this.writeDepthTexture?i.stencil&&(r.deleteRenderbuffer(i.stencil),i.stencil=null):(i.stencil=i.stencil||r.createRenderbuffer(),r.bindRenderbuffer(r.RENDERBUFFER,i.stencil),i.msaaBuffer?r.renderbufferStorageMultisample(r.RENDERBUFFER,i.multisample,r.DEPTH24_STENCIL8,t.width,t.height):r.renderbufferStorage(r.RENDERBUFFER,r.DEPTH_STENCIL,t.width,t.height),r.framebufferRenderbuffer(r.FRAMEBUFFER,r.DEPTH_STENCIL_ATTACHMENT,r.RENDERBUFFER,i.stencil))},e.prototype.canMultisampleFramebuffer=function(t){return 1!==this.renderer.context.webGLVersion&&t.colorTextures.length<=1&&!t.depthTexture},e.prototype.detectSamples=function(e){var r=this.msaaSamples,i=t.MSAA_QUALITY.NONE;if(e<=1||null===r)return i;for(var n=0;n=0&&this.managedFramebuffers.splice(n,1),t.disposeRunner.remove(this),e||(i.deleteFramebuffer(r.framebuffer),r.msaaBuffer&&i.deleteRenderbuffer(r.msaaBuffer),r.stencil&&i.deleteRenderbuffer(r.stencil)),r.blitFramebuffer&&r.blitFramebuffer.dispose()}},e.prototype.disposeAll=function(t){var e=this.managedFramebuffers;this.managedFramebuffers=[];for(var r=0;r=t.ENV.WEBGL2&&(r=e.getContext("webgl2",{})),r||((r=e.getContext("webgl",{})||e.getContext("experimental-webgl",{}))?r.getExtension("WEBGL_draw_buffers"):r=null),_i=r}return _i}function mi(e,r,i){if("precision"!==e.substring(0,9)){var n=r;return r===t.PRECISION.HIGH&&i!==t.PRECISION.HIGH&&(n=t.PRECISION.MEDIUM),"precision "+n+" float;\n"+e}return i!==t.PRECISION.HIGH&&"precision highp"===e.substring(0,15)?e.replace("precision highp","precision mediump"):e}var yi={float:1,vec2:2,vec3:3,vec4:4,int:1,ivec2:2,ivec3:3,ivec4:4,uint:1,uvec2:2,uvec3:3,uvec4:4,bool:1,bvec2:2,bvec3:3,bvec4:4,mat2:4,mat3:9,mat4:16,sampler2D:1};function gi(t){return yi[t]}var Ti=null,Ei={FLOAT:"float",FLOAT_VEC2:"vec2",FLOAT_VEC3:"vec3",FLOAT_VEC4:"vec4",INT:"int",INT_VEC2:"ivec2",INT_VEC3:"ivec3",INT_VEC4:"ivec4",UNSIGNED_INT:"uint",UNSIGNED_INT_VEC2:"uvec2",UNSIGNED_INT_VEC3:"uvec3",UNSIGNED_INT_VEC4:"uvec4",BOOL:"bool",BOOL_VEC2:"bvec2",BOOL_VEC3:"bvec3",BOOL_VEC4:"bvec4",FLOAT_MAT2:"mat2",FLOAT_MAT3:"mat3",FLOAT_MAT4:"mat4",SAMPLER_2D:"sampler2D",INT_SAMPLER_2D:"sampler2D",UNSIGNED_INT_SAMPLER_2D:"sampler2D",SAMPLER_CUBE:"samplerCube",INT_SAMPLER_CUBE:"samplerCube",UNSIGNED_INT_SAMPLER_CUBE:"samplerCube",SAMPLER_2D_ARRAY:"sampler2DArray",INT_SAMPLER_2D_ARRAY:"sampler2DArray",UNSIGNED_INT_SAMPLER_2D_ARRAY:"sampler2DArray"};function bi(t,e){if(!Ti){var r=Object.keys(Ei);Ti={};for(var i=0;i0&&(e+="\nelse "),r0?this.maskStack[this.maskStack.length-1]._colorMask:15;r!==e&&this.renderer.gl.colorMask(0!=(1&r),0!=(2&r),0!=(4&r),0!=(8&r))},e.prototype.destroy=function(){this.renderer=null},e}(),ki=function(){function t(t){this.renderer=t,this.maskStack=[],this.glConst=0}return t.prototype.getStackLength=function(){return this.maskStack.length},t.prototype.setMaskStack=function(t){var e=this.renderer.gl,r=this.getStackLength();this.maskStack=t;var i=this.getStackLength();i!==r&&(0===i?e.disable(this.glConst):(e.enable(this.glConst),this._useCurrent()))},t.prototype._useCurrent=function(){},t.prototype.destroy=function(){this.renderer=null,this.maskStack=null},t}(),Xi=new Ue,ji=[],Hi=function(t){function e(e){var r=t.call(this,e)||this;return r.glConst=U.ADAPTER.getWebGLRenderingContext().SCISSOR_TEST,r}return dr(e,t),e.prototype.getStackLength=function(){var t=this.maskStack[this.maskStack.length-1];return t?t._scissorCounter:0},e.prototype.calcScissorRect=function(t){var e;if(!t._scissorRectLocal){var r=t._scissorRect,i=t.maskObject,n=this.renderer,o=n.renderTexture,s=i.getBounds(!0,null!==(e=ji.pop())&&void 0!==e?e:new Ce);this.roundFrameToPixels(s,o.current?o.current.resolution:n.resolution,o.sourceFrame,o.destinationFrame,n.projection.transform),r&&s.fit(r),t._scissorRectLocal=s}},e.isMatrixRotated=function(t){if(!t)return!1;var e=t.a,r=t.b,i=t.c,n=t.d;return(Math.abs(r)>1e-4||Math.abs(i)>1e-4)&&(Math.abs(e)>1e-4||Math.abs(n)>1e-4)},e.prototype.testScissor=function(t){var r=t.maskObject;if(!r.isFastRect||!r.isFastRect())return!1;if(e.isMatrixRotated(r.worldTransform))return!1;if(e.isMatrixRotated(this.renderer.projection.transform))return!1;this.calcScissorRect(t);var i=t._scissorRectLocal;return i.width>0&&i.height>0},e.prototype.roundFrameToPixels=function(t,r,i,n,o){e.isMatrixRotated(o)||((o=o?Xi.copyFrom(o):Xi.identity()).translate(-i.x,-i.y).scale(n.width/i.width,n.height/i.height).translate(n.x,n.y),this.renderer.filter.transformAABB(o,t),t.fit(n),t.x=Math.round(t.x*r),t.y=Math.round(t.y*r),t.width=Math.round(t.width*r),t.height=Math.round(t.height*r))},e.prototype.push=function(t){t._scissorRectLocal||this.calcScissorRect(t);var e=this.renderer.gl;t._scissorRect||e.enable(e.SCISSOR_TEST),t._scissorCounter++,t._scissorRect=t._scissorRectLocal,this._useCurrent()},e.prototype.pop=function(t){var e=this.renderer.gl;t&&ji.push(t._scissorRectLocal),this.getStackLength()>0?this._useCurrent():e.disable(e.SCISSOR_TEST)},e.prototype._useCurrent=function(){var t,e=this.maskStack[this.maskStack.length-1]._scissorRect;t=this.renderer.renderTexture.current?e.y:this.renderer.height-e.height-e.y,this.renderer.gl.scissor(e.x,t,e.width,e.height)},e}(ki),Yi=function(t){function e(e){var r=t.call(this,e)||this;return r.glConst=U.ADAPTER.getWebGLRenderingContext().STENCIL_TEST,r}return dr(e,t),e.prototype.getStackLength=function(){var t=this.maskStack[this.maskStack.length-1];return t?t._stencilCounter:0},e.prototype.push=function(t){var e=t.maskObject,r=this.renderer.gl,i=t._stencilCounter;0===i&&(this.renderer.framebuffer.forceStencil(),r.clearStencil(0),r.clear(r.STENCIL_BUFFER_BIT),r.enable(r.STENCIL_TEST)),t._stencilCounter++;var n=t._colorMask;0!==n&&(t._colorMask=0,r.colorMask(!1,!1,!1,!1)),r.stencilFunc(r.EQUAL,i,4294967295),r.stencilOp(r.KEEP,r.KEEP,r.INCR),e.renderable=!0,e.render(this.renderer),this.renderer.batch.flush(),e.renderable=!1,0!==n&&(t._colorMask=n,r.colorMask(0!=(1&n),0!=(2&n),0!=(4&n),0!=(8&n))),this._useCurrent()},e.prototype.pop=function(t){var e=this.renderer.gl;if(0===this.getStackLength())e.disable(e.STENCIL_TEST);else{var r=0!==this.maskStack.length?this.maskStack[this.maskStack.length-1]:null,i=r?r._colorMask:15;0!==i&&(r._colorMask=0,e.colorMask(!1,!1,!1,!1)),e.stencilOp(e.KEEP,e.KEEP,e.DECR),t.renderable=!0,t.render(this.renderer),this.renderer.batch.flush(),t.renderable=!1,0!==i&&(r._colorMask=i,e.colorMask(0!=(1&i),0!=(2&i),0!=(4&i),0!=(8&i))),this._useCurrent()}},e.prototype._useCurrent=function(){var t=this.renderer.gl;t.stencilFunc(t.EQUAL,this.getStackLength(),4294967295),t.stencilOp(t.KEEP,t.KEEP,t.KEEP)},e}(ki),Vi=function(){function t(t){this.renderer=t,this.destinationFrame=null,this.sourceFrame=null,this.defaultFrame=null,this.projectionMatrix=new Ue,this.transform=null}return t.prototype.update=function(t,e,r,i){this.destinationFrame=t||this.destinationFrame||this.defaultFrame,this.sourceFrame=e||this.sourceFrame||t,this.calculateProjection(this.destinationFrame,this.sourceFrame,r,i),this.transform&&this.projectionMatrix.append(this.transform);var n=this.renderer;n.globalUniforms.uniforms.projectionMatrix=this.projectionMatrix,n.globalUniforms.update(),n.shader.shader&&n.shader.syncUniformGroup(n.shader.shader.uniforms.globals)},t.prototype.calculateProjection=function(t,e,r,i){var n=this.projectionMatrix,o=i?-1:1;n.identity(),n.a=1/e.width*2,n.d=o*(1/e.height*2),n.tx=-1-e.x*n.a,n.ty=-o-e.y*n.d},t.prototype.setTransform=function(t){},t.prototype.destroy=function(){this.renderer=null},t}(),zi=new Ce,Wi=new Ce,qi=function(){function t(t){this.renderer=t,this.clearColor=t._backgroundColorRgba,this.defaultMaskStack=[],this.current=null,this.sourceFrame=new Ce,this.destinationFrame=new Ce,this.viewportFrame=new Ce}return t.prototype.bind=function(t,e,r){void 0===t&&(t=null);var i,n,o,s=this.renderer;this.current=t,t?(o=(i=t.baseTexture).resolution,e||(zi.width=t.frame.width,zi.height=t.frame.height,e=zi),r||(Wi.x=t.frame.x,Wi.y=t.frame.y,Wi.width=e.width,Wi.height=e.height,r=Wi),n=i.framebuffer):(o=s.resolution,e||(zi.width=s.screen.width,zi.height=s.screen.height,e=zi),r||((r=zi).width=e.width,r.height=e.height));var a=this.viewportFrame;a.x=r.x*o,a.y=r.y*o,a.width=r.width*o,a.height=r.height*o,t||(a.y=s.view.height-(a.y+a.height)),a.ceil(),this.renderer.framebuffer.bind(n,a),this.renderer.projection.update(r,e,o,!n),t?this.renderer.mask.setMaskStack(i.maskStack):this.renderer.mask.setMaskStack(this.defaultMaskStack),this.sourceFrame.copyFrom(e),this.destinationFrame.copyFrom(r)},t.prototype.clear=function(t,e){t=this.current?t||this.current.baseTexture.clearColor:t||this.clearColor;var r=this.destinationFrame,i=this.current?this.current.baseTexture:this.renderer.screen,n=r.width!==i.width||r.height!==i.height;if(n){var o=this.viewportFrame,s=o.x,a=o.y,h=o.width,u=o.height;s=Math.round(s),a=Math.round(a),h=Math.round(h),u=Math.round(u),this.renderer.gl.enable(this.renderer.gl.SCISSOR_TEST),this.renderer.gl.scissor(s,a,h,u)}this.renderer.framebuffer.clear(t[0],t[1],t[2],t[3],e),n&&this.renderer.scissor.pop()},t.prototype.resize=function(){this.bind(null)},t.prototype.reset=function(){this.bind(null)},t.prototype.destroy=function(){this.renderer=null},t}();function Ki(t,e,r,i,n){r.buffer.update(n)}var Zi={float:"\n data[offset] = v;\n ",vec2:"\n data[offset] = v[0];\n data[offset+1] = v[1];\n ",vec3:"\n data[offset] = v[0];\n data[offset+1] = v[1];\n data[offset+2] = v[2];\n\n ",vec4:"\n data[offset] = v[0];\n data[offset+1] = v[1];\n data[offset+2] = v[2];\n data[offset+3] = v[3];\n ",mat2:"\n data[offset] = v[0];\n data[offset+1] = v[1];\n\n data[offset+4] = v[2];\n data[offset+5] = v[3];\n ",mat3:"\n data[offset] = v[0];\n data[offset+1] = v[1];\n data[offset+2] = v[2];\n\n data[offset + 4] = v[3];\n data[offset + 5] = v[4];\n data[offset + 6] = v[5];\n\n data[offset + 8] = v[6];\n data[offset + 9] = v[7];\n data[offset + 10] = v[8];\n ",mat4:"\n for(var i = 0; i < 16; i++)\n {\n data[offset + i] = v[i];\n }\n "},Qi={float:4,vec2:8,vec3:12,vec4:16,int:4,ivec2:8,ivec3:12,ivec4:16,uint:4,uvec2:8,uvec3:12,uvec4:16,bool:4,bvec2:8,bvec3:12,bvec4:16,mat2:32,mat3:48,mat4:64};function Ji(t){for(var e=t.map((function(t){return{data:t,offset:0,dataLen:0,dirty:0}})),r=0,i=0,n=0,o=0;o1&&(r=Math.max(r,16)*s.data.size),s.dataLen=r,i%r!=0&&i<16){var a=i%r%16;i+=a,n+=a}i+r>16?(n=16*Math.ceil(n/16),s.offset=n,n+=r,i=r):(s.offset=n,i+=r,n+=r)}return{uboElements:e,size:n=16*Math.ceil(n/16)}}function $i(t,e){var r=[];for(var i in t)e[i]&&r.push(e[i]);return r.sort((function(t,e){return t.index-e.index})),r}function tn(t,e){if(!t.autoManage)return{size:0,syncFunc:Ki};for(var r=Ji($i(t.uniforms,e)),i=r.uboElements,n=r.size,o=["\n var v = null;\n var v2 = null;\n var cv = null;\n var t = 0;\n var gl = renderer.gl\n var index = 0;\n var data = buffer.data;\n "],s=0;s1){var f=gi(a.data.type),p=Math.max(Qi[a.data.type]/16,1),_=f/p,v=(4-_%4)%4;o.push("\n cv = ud."+u+".value;\n v = uv."+u+";\n offset = "+a.offset/4+";\n\n t = 0;\n\n for(var i=0; i < "+a.data.size*p+"; i++)\n {\n for(var j = 0; j < "+_+"; j++)\n {\n data[offset++] = v[t++];\n }\n offset += "+v+";\n }\n\n ")}else{var m=Zi[a.data.type];o.push("\n cv = ud."+u+".value;\n v = uv."+u+";\n offset = "+a.offset/4+";\n "+m+";\n ")}}return o.push("\n renderer.buffer.update(buffer);\n "),{size:n,syncFunc:new Function("ud","uv","renderer","syncData","buffer",o.join("\n"))}}var en=function(){function t(t,e){this.program=t,this.uniformData=e,this.uniformGroups={},this.uniformDirtyGroups={},this.uniformBufferBindings={}}return t.prototype.destroy=function(){this.uniformData=null,this.uniformGroups=null,this.uniformDirtyGroups=null,this.uniformBufferBindings=null,this.program=null},t}();function rn(t,e){var r=ui(t,t.VERTEX_SHADER,e.vertexSrc),i=ui(t,t.FRAGMENT_SHADER,e.fragmentSrc),n=t.createProgram();if(t.attachShader(n,r),t.attachShader(n,i),t.linkProgram(n),t.getProgramParameter(n,t.LINK_STATUS)||function(t,e,r,i){t.getProgramParameter(e,t.LINK_STATUS)||(t.getShaderParameter(r,t.COMPILE_STATUS)||li(t,r),t.getShaderParameter(i,t.COMPILE_STATUS)||li(t,i),console.error("PixiJS Error: Could not initialize shader."),""!==t.getProgramInfoLog(e)&&console.warn("PixiJS Warning: gl.getProgramInfoLog()",t.getProgramInfoLog(e)))}(t,n,r,i),e.attributeData=function(t,e){for(var r={},i=e.getProgramParameter(t,e.ACTIVE_ATTRIBUTES),n=0;ne?1:-1}));for(var s=0;s>=1,r++;this.stateId=t.data}for(r=0;rthis.checkCountMax&&(this.checkCount=0,this.run())))},e.prototype.run=function(){for(var t=this.renderer.texture,e=t.managedTextures,r=!1,i=0;ithis.maxIdle&&(t.destroyTexture(n,!0),e[i]=null,r=!0)}if(r){var o=0;for(i=0;i=0;i--)this.unload(t.children[i])},e.prototype.destroy=function(){this.renderer=null},e}(),un=function(e){this.texture=e,this.width=-1,this.height=-1,this.dirtyId=-1,this.dirtyStyleId=-1,this.mipmap=!1,this.wrapMode=33071,this.type=t.TYPES.UNSIGNED_BYTE,this.internalFormat=t.FORMATS.RGBA,this.samplerType=0},ln=function(){function e(t){this.renderer=t,this.boundTextures=[],this.currentLocation=-1,this.managedTextures=[],this._unknownBoundTextures=!1,this.unknownTexture=new mr,this.hasIntegerTextures=!1}return e.prototype.contextChange=function(){var e=this.gl=this.renderer.gl;this.CONTEXT_UID=this.renderer.CONTEXT_UID,this.webGLVersion=this.renderer.context.webGLVersion,this.internalFormats=function(e){var r,i,n,o,s,a,h,u,l,c,d,f,p,_,v,m,y,g,T,E,b,x,A;return"WebGL2RenderingContext"in globalThis&&e instanceof globalThis.WebGL2RenderingContext?((r={})[t.TYPES.UNSIGNED_BYTE]=((i={})[t.FORMATS.RGBA]=e.RGBA8,i[t.FORMATS.RGB]=e.RGB8,i[t.FORMATS.RG]=e.RG8,i[t.FORMATS.RED]=e.R8,i[t.FORMATS.RGBA_INTEGER]=e.RGBA8UI,i[t.FORMATS.RGB_INTEGER]=e.RGB8UI,i[t.FORMATS.RG_INTEGER]=e.RG8UI,i[t.FORMATS.RED_INTEGER]=e.R8UI,i[t.FORMATS.ALPHA]=e.ALPHA,i[t.FORMATS.LUMINANCE]=e.LUMINANCE,i[t.FORMATS.LUMINANCE_ALPHA]=e.LUMINANCE_ALPHA,i),r[t.TYPES.BYTE]=((n={})[t.FORMATS.RGBA]=e.RGBA8_SNORM,n[t.FORMATS.RGB]=e.RGB8_SNORM,n[t.FORMATS.RG]=e.RG8_SNORM,n[t.FORMATS.RED]=e.R8_SNORM,n[t.FORMATS.RGBA_INTEGER]=e.RGBA8I,n[t.FORMATS.RGB_INTEGER]=e.RGB8I,n[t.FORMATS.RG_INTEGER]=e.RG8I,n[t.FORMATS.RED_INTEGER]=e.R8I,n),r[t.TYPES.UNSIGNED_SHORT]=((o={})[t.FORMATS.RGBA_INTEGER]=e.RGBA16UI,o[t.FORMATS.RGB_INTEGER]=e.RGB16UI,o[t.FORMATS.RG_INTEGER]=e.RG16UI,o[t.FORMATS.RED_INTEGER]=e.R16UI,o[t.FORMATS.DEPTH_COMPONENT]=e.DEPTH_COMPONENT16,o),r[t.TYPES.SHORT]=((s={})[t.FORMATS.RGBA_INTEGER]=e.RGBA16I,s[t.FORMATS.RGB_INTEGER]=e.RGB16I,s[t.FORMATS.RG_INTEGER]=e.RG16I,s[t.FORMATS.RED_INTEGER]=e.R16I,s),r[t.TYPES.UNSIGNED_INT]=((a={})[t.FORMATS.RGBA_INTEGER]=e.RGBA32UI,a[t.FORMATS.RGB_INTEGER]=e.RGB32UI,a[t.FORMATS.RG_INTEGER]=e.RG32UI,a[t.FORMATS.RED_INTEGER]=e.R32UI,a[t.FORMATS.DEPTH_COMPONENT]=e.DEPTH_COMPONENT24,a),r[t.TYPES.INT]=((h={})[t.FORMATS.RGBA_INTEGER]=e.RGBA32I,h[t.FORMATS.RGB_INTEGER]=e.RGB32I,h[t.FORMATS.RG_INTEGER]=e.RG32I,h[t.FORMATS.RED_INTEGER]=e.R32I,h),r[t.TYPES.FLOAT]=((u={})[t.FORMATS.RGBA]=e.RGBA32F,u[t.FORMATS.RGB]=e.RGB32F,u[t.FORMATS.RG]=e.RG32F,u[t.FORMATS.RED]=e.R32F,u[t.FORMATS.DEPTH_COMPONENT]=e.DEPTH_COMPONENT32F,u),r[t.TYPES.HALF_FLOAT]=((l={})[t.FORMATS.RGBA]=e.RGBA16F,l[t.FORMATS.RGB]=e.RGB16F,l[t.FORMATS.RG]=e.RG16F,l[t.FORMATS.RED]=e.R16F,l),r[t.TYPES.UNSIGNED_SHORT_5_6_5]=((c={})[t.FORMATS.RGB]=e.RGB565,c),r[t.TYPES.UNSIGNED_SHORT_4_4_4_4]=((d={})[t.FORMATS.RGBA]=e.RGBA4,d),r[t.TYPES.UNSIGNED_SHORT_5_5_5_1]=((f={})[t.FORMATS.RGBA]=e.RGB5_A1,f),r[t.TYPES.UNSIGNED_INT_2_10_10_10_REV]=((p={})[t.FORMATS.RGBA]=e.RGB10_A2,p[t.FORMATS.RGBA_INTEGER]=e.RGB10_A2UI,p),r[t.TYPES.UNSIGNED_INT_10F_11F_11F_REV]=((_={})[t.FORMATS.RGB]=e.R11F_G11F_B10F,_),r[t.TYPES.UNSIGNED_INT_5_9_9_9_REV]=((v={})[t.FORMATS.RGB]=e.RGB9_E5,v),r[t.TYPES.UNSIGNED_INT_24_8]=((m={})[t.FORMATS.DEPTH_STENCIL]=e.DEPTH24_STENCIL8,m),r[t.TYPES.FLOAT_32_UNSIGNED_INT_24_8_REV]=((y={})[t.FORMATS.DEPTH_STENCIL]=e.DEPTH32F_STENCIL8,y),A=r):((g={})[t.TYPES.UNSIGNED_BYTE]=((T={})[t.FORMATS.RGBA]=e.RGBA,T[t.FORMATS.RGB]=e.RGB,T[t.FORMATS.ALPHA]=e.ALPHA,T[t.FORMATS.LUMINANCE]=e.LUMINANCE,T[t.FORMATS.LUMINANCE_ALPHA]=e.LUMINANCE_ALPHA,T),g[t.TYPES.UNSIGNED_SHORT_5_6_5]=((E={})[t.FORMATS.RGB]=e.RGB,E),g[t.TYPES.UNSIGNED_SHORT_4_4_4_4]=((b={})[t.FORMATS.RGBA]=e.RGBA,b),g[t.TYPES.UNSIGNED_SHORT_5_5_5_1]=((x={})[t.FORMATS.RGBA]=e.RGBA,x),A=g),A}(e);var r=e.getParameter(e.MAX_TEXTURE_IMAGE_UNITS);this.boundTextures.length=r;for(var i=0;i=0;--s){var a=i[s];a&&a._glTextures[o].samplerType!==t.SAMPLER_TYPES.FLOAT&&this.renderer.texture.unbind(a)}},e.prototype.initTexture=function(t){var e=new un(this.gl.createTexture());return e.dirtyId=-1,t._glTextures[this.CONTEXT_UID]=e,this.managedTextures.push(t),t.on("dispose",this.destroyTexture,this),e},e.prototype.initTextureType=function(e,r){var i,n;r.internalFormat=null!==(n=null===(i=this.internalFormats[e.type])||void 0===i?void 0:i[e.format])&&void 0!==n?n:e.format,2===this.webGLVersion&&e.type===t.TYPES.HALF_FLOAT?r.type=this.gl.HALF_FLOAT:r.type=e.type},e.prototype.updateTexture=function(e){var r=e._glTextures[this.CONTEXT_UID];if(r){var i=this.renderer;if(this.initTextureType(e,r),e.resource&&e.resource.upload(i,e,r))r.samplerType!==t.SAMPLER_TYPES.FLOAT&&(this.hasIntegerTextures=!0);else{var n=e.realWidth,o=e.realHeight,s=i.gl;(r.width!==n||r.height!==o||r.dirtyId<0)&&(r.width=n,r.height=o,s.texImage2D(e.target,0,r.internalFormat,n,o,0,e.format,r.type,null))}e.dirtyStyleId!==r.dirtyStyleId&&this.updateTextureStyle(e),r.dirtyId=e.dirtyId}},e.prototype.destroyTexture=function(t,e){var r=this.gl;if((t=t.castToBaseTexture())._glTextures[this.CONTEXT_UID]&&(this.unbind(t),r.deleteTexture(t._glTextures[this.CONTEXT_UID].texture),t.off("dispose",this.destroyTexture,this),delete t._glTextures[this.CONTEXT_UID],!e)){var i=this.managedTextures.indexOf(t);-1!==i&&fe(this.managedTextures,i,1)}},e.prototype.updateTextureStyle=function(e){var r=e._glTextures[this.CONTEXT_UID];r&&(e.mipmap!==t.MIPMAP_MODES.POW2&&2===this.webGLVersion||e.isPowerOfTwo?r.mipmap=e.mipmap>=1:r.mipmap=!1,2===this.webGLVersion||e.isPowerOfTwo?r.wrapMode=e.wrapMode:r.wrapMode=t.WRAP_MODES.CLAMP,e.resource&&e.resource.style(this.renderer,e,r)||this.setStyle(e,r),r.dirtyStyleId=e.dirtyStyleId)},e.prototype.setStyle=function(e,r){var i=this.gl;if(r.mipmap&&e.mipmap!==t.MIPMAP_MODES.ON_MANUAL&&i.generateMipmap(e.target),i.texParameteri(e.target,i.TEXTURE_WRAP_S,r.wrapMode),i.texParameteri(e.target,i.TEXTURE_WRAP_T,r.wrapMode),r.mipmap){i.texParameteri(e.target,i.TEXTURE_MIN_FILTER,e.scaleMode===t.SCALE_MODES.LINEAR?i.LINEAR_MIPMAP_LINEAR:i.NEAREST_MIPMAP_NEAREST);var n=this.renderer.context.extensions.anisotropicFiltering;if(n&&e.anisotropicLevel>0&&e.scaleMode===t.SCALE_MODES.LINEAR){var o=Math.min(e.anisotropicLevel,i.getParameter(n.MAX_TEXTURE_MAX_ANISOTROPY_EXT));i.texParameterf(e.target,n.TEXTURE_MAX_ANISOTROPY_EXT,o)}}else i.texParameteri(e.target,i.TEXTURE_MIN_FILTER,e.scaleMode===t.SCALE_MODES.LINEAR?i.LINEAR:i.NEAREST);i.texParameteri(e.target,i.TEXTURE_MAG_FILTER,e.scaleMode===t.SCALE_MODES.LINEAR?i.LINEAR:i.NEAREST)},e.prototype.destroy=function(){this.renderer=null},e}(),cn={__proto__:null,FilterSystem:Jr,BatchSystem:ti,ContextSystem:ri,FramebufferSystem:oi,GeometrySystem:ai,MaskSystem:Ui,ScissorSystem:Hi,StencilSystem:Yi,ProjectionSystem:Vi,RenderTextureSystem:qi,ShaderSystem:sn,StateSystem:an,TextureGCSystem:hn,TextureSystem:ln},dn=new Ue,fn=function(e){function r(r,i){void 0===r&&(r=t.RENDERER_TYPE.UNKNOWN);var n=e.call(this)||this;return i=Object.assign({},U.RENDER_OPTIONS,i),n.options=i,n.type=r,n.screen=new Ce(0,0,i.width,i.height),n.view=i.view||U.ADAPTER.createCanvas(),n.resolution=i.resolution||U.RESOLUTION,n.useContextAlpha=i.useContextAlpha,n.autoDensity=!!i.autoDensity,n.preserveDrawingBuffer=i.preserveDrawingBuffer,n.clearBeforeRender=i.clearBeforeRender,n._backgroundColor=0,n._backgroundColorRgba=[0,0,0,1],n._backgroundColorString="#000000",n.backgroundColor=i.backgroundColor||n._backgroundColor,n.backgroundAlpha=i.backgroundAlpha,void 0!==i.transparent&&(n.useContextAlpha=i.transparent,n.backgroundAlpha=i.transparent?0:1),n._lastObjectRendered=null,n.plugins={},n}return dr(r,e),r.prototype.initPlugins=function(t){for(var e in t)this.plugins[e]=new t[e](this)},Object.defineProperty(r.prototype,"width",{get:function(){return this.view.width},enumerable:!1,configurable:!0}),Object.defineProperty(r.prototype,"height",{get:function(){return this.view.height},enumerable:!1,configurable:!0}),r.prototype.resize=function(t,e){this.view.width=Math.round(t*this.resolution),this.view.height=Math.round(e*this.resolution);var r=this.view.width/this.resolution,i=this.view.height/this.resolution;this.screen.width=r,this.screen.height=i,this.autoDensity&&(this.view.style.width=r+"px",this.view.style.height=i+"px"),this.emit("resize",r,i)},r.prototype.generateTexture=function(t,e,r,i){void 0===e&&(e={}),"number"==typeof e&&(e={scaleMode:e,resolution:r,region:i});var n=e.region,o=function(t,e){var r={};for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&e.indexOf(i)<0&&(r[i]=t[i]);if(null!=t&&"function"==typeof Object.getOwnPropertySymbols){var n=0;for(i=Object.getOwnPropertySymbols(t);n=t.data.byteLength)e.bufferSubData(t.type,0,t.data);else{var n=t.static?e.STATIC_DRAW:e.DYNAMIC_DRAW;i.byteLength=t.data.byteLength,e.bufferData(t.type,t.data,n)}},t.prototype.dispose=function(t,e){if(this.managedBuffers[t.id]){delete this.managedBuffers[t.id];var r=t._glBuffers[this.CONTEXT_UID],i=this.gl;t.disposeRunner.remove(this),r&&(e||i.deleteBuffer(r.buffer),delete t._glBuffers[this.CONTEXT_UID])}},t.prototype.disposeAll=function(t){for(var e=Object.keys(this.managedBuffers),r=0;r=t.MSAA_QUALITY.HIGH?this.multisample=t.MSAA_QUALITY.HIGH:e>=t.MSAA_QUALITY.MEDIUM?this.multisample=t.MSAA_QUALITY.MEDIUM:e>=t.MSAA_QUALITY.LOW?this.multisample=t.MSAA_QUALITY.LOW:this.multisample=t.MSAA_QUALITY.NONE},r.prototype.addSystem=function(t,e){var r=new t(this);if(this[e])throw new Error('Whoops! The name "'+e+'" is already in use');for(var i in this[e]=r,this.runners)this.runners[i].add(r);return this},r.prototype.render=function(t,e){var r,i,n,o;if(e&&(e instanceof Fr?(r=e,i=arguments[2],n=arguments[3],o=arguments[4]):(r=e.renderTexture,i=e.clear,n=e.transform,o=e.skipUpdateTransform)),this.renderingToScreen=!r,this.runners.prerender.emit(),this.emit("prerender"),this.projection.transform=n,!this.context.isLost){if(r||(this._lastObjectRendered=t),!o){var s=t.enableTempParent();t.updateTransform(),t.disableTempParent(s)}this.renderTexture.bind(r),this.batch.currentRenderer.start(),(void 0!==i?i:this.clearBeforeRender)&&this.renderTexture.clear(),t.render(this),this.batch.currentRenderer.flush(),r&&r.baseTexture.update(),this.runners.postrender.emit(),this.projection.transform=null,this.emit("postrender")}},r.prototype.generateTexture=function(t,r,i,n){void 0===r&&(r={});var o=e.prototype.generateTexture.call(this,t,r,i,n);return this.framebuffer.blit(),o},r.prototype.resize=function(t,r){e.prototype.resize.call(this,t,r),this.runners.resize.emit(this.screen.height,this.screen.width)},r.prototype.reset=function(){return this.runners.reset.emit(),this},r.prototype.clear=function(){this.renderTexture.bind(),this.renderTexture.clear()},r.prototype.destroy=function(t){for(var r in this.runners.destroy.emit(),this.runners)this.runners[r].destroy();e.prototype.destroy.call(this,t),this.gl=null},Object.defineProperty(r.prototype,"extract",{get:function(){return this.plugins.extract},enumerable:!1,configurable:!0}),r.registerPlugin=function(e,r){nr.add({name:e,type:t.ExtensionType.RendererPlugin,ref:r})},r.__plugins={},r}(fn);function mn(t){return vn.create(t)}nr.handleByMap(t.ExtensionType.RendererPlugin,vn.__plugins);var yn="attribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\n\nuniform mat3 projectionMatrix;\n\nvarying vec2 vTextureCoord;\n\nvoid main(void)\n{\n gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);\n vTextureCoord = aTextureCoord;\n}",gn="attribute vec2 aVertexPosition;\n\nuniform mat3 projectionMatrix;\n\nvarying vec2 vTextureCoord;\n\nuniform vec4 inputSize;\nuniform vec4 outputFrame;\n\nvec4 filterVertexPosition( void )\n{\n vec2 position = aVertexPosition * max(outputFrame.zw, vec2(0.)) + outputFrame.xy;\n\n return vec4((projectionMatrix * vec3(position, 1.0)).xy, 0.0, 1.0);\n}\n\nvec2 filterTextureCoord( void )\n{\n return aVertexPosition * (outputFrame.zw * inputSize.zw);\n}\n\nvoid main(void)\n{\n gl_Position = filterVertexPosition();\n vTextureCoord = filterTextureCoord();\n}\n",Tn=function(){function t(t){this.renderer=t}return t.prototype.destroy=function(){this.renderer=null},t}(),En=function(){this.texArray=null,this.blend=0,this.type=t.DRAW_MODES.TRIANGLES,this.start=0,this.size=0,this.data=null},bn=function(){function t(){this.elements=[],this.ids=[],this.count=0}return t.prototype.clear=function(){for(var t=0;tthis.size&&this.flush(),this._vertexCount+=t.vertexData.length/2,this._indexCount+=t.indices.length,this._bufferedTextures[this._bufferSize]=t._texture.baseTexture,this._bufferedElements[this._bufferSize++]=t)},r.prototype.buildTexturesAndDrawCalls=function(){var t=this._bufferedTextures,e=this.MAX_TEXTURES,i=r._textureArrayPool,n=this.renderer.batch,o=this._tempBoundTextures,s=this.renderer.textureGC.count,a=++mr._globalBatch,h=0,u=i[0],l=0;n.copyBoundTextures(o,e);for(var c=0;c=e&&(n.boundArray(u,o,a,e),this.buildDrawCalls(u,l,c),l=c,u=i[++h],++a),d._batchEnabled=a,d.touched=s,u.elements[u.count++]=d)}for(u.count>0&&(n.boundArray(u,o,a,e),this.buildDrawCalls(u,l,this._bufferSize),++h,++a),c=0;c0&&(e+="\nelse "),r title : "+t.title+"
tabIndex: "+t.tabIndex},e.prototype.capHitArea=function(t){t.x<0&&(t.width+=t.x,t.x=0),t.y<0&&(t.height+=t.y,t.y=0);var e=this.renderer,r=e.width,i=e.height;t.x+t.width>r&&(t.width=r-t.x),t.y+t.height>i&&(t.height=i-t.y)},e.prototype.addChild=function(t){var e=this.pool.pop();e||((e=document.createElement("button")).style.width="100px",e.style.height="100px",e.style.backgroundColor=this.debug?"rgba(255,255,255,0.5)":"transparent",e.style.position="absolute",e.style.zIndex=2..toString(),e.style.borderStyle="none",navigator.userAgent.toLowerCase().indexOf("chrome")>-1?e.setAttribute("aria-live","off"):e.setAttribute("aria-live","polite"),navigator.userAgent.match(/rv:.*Gecko\//)?e.setAttribute("aria-relevant","additions"):e.setAttribute("aria-relevant","text"),e.addEventListener("click",this._onClick.bind(this)),e.addEventListener("focus",this._onFocus.bind(this)),e.addEventListener("focusout",this._onFocusOut.bind(this))),e.style.pointerEvents=t.accessiblePointerEvents,e.type=t.accessibleType,t.accessibleTitle&&null!==t.accessibleTitle?e.title=t.accessibleTitle:t.accessibleHint&&null!==t.accessibleHint||(e.title="displayObject "+t.tabIndex),t.accessibleHint&&null!==t.accessibleHint&&e.setAttribute("aria-label",t.accessibleHint),this.debug&&this.updateDebugHTML(e),t._accessibleActive=!0,t._accessibleDiv=e,e.displayObject=t,this.children.push(t),this.div.appendChild(t._accessibleDiv),t._accessibleDiv.tabIndex=t.tabIndex},e.prototype._onClick=function(t){var e=this.renderer.plugins.interaction,r=t.target.displayObject,i=e.eventData;e.dispatchEvent(r,"click",i),e.dispatchEvent(r,"pointertap",i),e.dispatchEvent(r,"tap",i)},e.prototype._onFocus=function(t){t.target.getAttribute("aria-live")||t.target.setAttribute("aria-live","assertive");var e=this.renderer.plugins.interaction,r=t.target.displayObject,i=e.eventData;e.dispatchEvent(r,"mouseover",i)},e.prototype._onFocusOut=function(t){t.target.getAttribute("aria-live")||t.target.setAttribute("aria-live","polite");var e=this.renderer.plugins.interaction,r=t.target.displayObject,i=e.eventData;e.dispatchEvent(r,"mouseout",i)},e.prototype._onKeyDown=function(t){9===t.keyCode&&this.activate()},e.prototype._onMouseMove=function(t){0===t.movementX&&0===t.movementY||this.deactivate()},e.prototype.destroy=function(){this.destroyTouchHook(),this.div=null,globalThis.document.removeEventListener("mousemove",this._onMouseMove,!0),globalThis.removeEventListener("keydown",this._onKeyDown),this.pool=null,this.children=null,this.renderer=null},e.extension={name:"accessibility",type:[t.ExtensionType.RendererPlugin,t.ExtensionType.CanvasRendererPlugin]},e}(),Gn=function(){function t(){this.pressure=0,this.rotationAngle=0,this.twist=0,this.tangentialPressure=0,this.global=new De,this.target=null,this.originalEvent=null,this.identifier=null,this.isPrimary=!1,this.button=0,this.buttons=0,this.width=0,this.height=0,this.tiltX=0,this.tiltY=0,this.pointerType=null,this.pressure=0,this.rotationAngle=0,this.twist=0,this.tangentialPressure=0}return Object.defineProperty(t.prototype,"pointerId",{get:function(){return this.identifier},enumerable:!1,configurable:!0}),t.prototype.getLocalPosition=function(t,e,r){return t.worldTransform.applyInverse(r||this.global,e)},t.prototype.copyEvent=function(t){"isPrimary"in t&&t.isPrimary&&(this.isPrimary=!0),this.button="button"in t&&t.button;var e="buttons"in t&&t.buttons;this.buttons=Number.isInteger(e)?e:"which"in t&&t.which,this.width="width"in t&&t.width,this.height="height"in t&&t.height,this.tiltX="tiltX"in t&&t.tiltX,this.tiltY="tiltY"in t&&t.tiltY,this.pointerType="pointerType"in t&&t.pointerType,this.pressure="pressure"in t&&t.pressure,this.rotationAngle="rotationAngle"in t&&t.rotationAngle,this.twist="twist"in t&&t.twist||0,this.tangentialPressure="tangentialPressure"in t&&t.tangentialPressure||0},t.prototype.reset=function(){this.isPrimary=!1},t}(),Un=function(t,e){return Un=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r])},Un(t,e)},kn=function(){function t(){this.stopped=!1,this.stopsPropagatingAt=null,this.stopPropagationHint=!1,this.target=null,this.currentTarget=null,this.type=null,this.data=null}return t.prototype.stopPropagation=function(){this.stopped=!0,this.stopPropagationHint=!0,this.stopsPropagatingAt=this.currentTarget},t.prototype.reset=function(){this.stopped=!1,this.stopsPropagatingAt=null,this.stopPropagationHint=!1,this.currentTarget=null,this.target=null},t}(),Xn=function(){function t(e){this._pointerId=e,this._flags=t.FLAGS.NONE}return t.prototype._doSet=function(t,e){this._flags=e?this._flags|t:this._flags&~t},Object.defineProperty(t.prototype,"pointerId",{get:function(){return this._pointerId},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"flags",{get:function(){return this._flags},set:function(t){this._flags=t},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"none",{get:function(){return this._flags===t.FLAGS.NONE},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"over",{get:function(){return 0!=(this._flags&t.FLAGS.OVER)},set:function(e){this._doSet(t.FLAGS.OVER,e)},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"rightDown",{get:function(){return 0!=(this._flags&t.FLAGS.RIGHT_DOWN)},set:function(e){this._doSet(t.FLAGS.RIGHT_DOWN,e)},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"leftDown",{get:function(){return 0!=(this._flags&t.FLAGS.LEFT_DOWN)},set:function(e){this._doSet(t.FLAGS.LEFT_DOWN,e)},enumerable:!1,configurable:!0}),t.FLAGS=Object.freeze({NONE:0,OVER:1,LEFT_DOWN:2,RIGHT_DOWN:4}),t}(),jn=function(){function t(){this._tempPoint=new De}return t.prototype.recursiveFindHit=function(t,e,r,i,n){var o;if(!e||!e.visible)return!1;var s=t.data.global,a=!1,h=n=e.interactive||n,u=!0;if(e.hitArea)i&&(e.worldTransform.applyInverse(s,this._tempPoint),e.hitArea.contains(this._tempPoint.x,this._tempPoint.y)?a=!0:(i=!1,u=!1)),h=!1;else if(e._mask&&i){var l=e._mask.isMaskData?e._mask.maskObject:e._mask;l&&!(null===(o=l.containsPoint)||void 0===o?void 0:o.call(l,s))&&(i=!1)}if(u&&e.interactiveChildren&&e.children)for(var c=e.children,d=c.length-1;d>=0;d--){var f=c[d],p=this.recursiveFindHit(t,f,r,i,h);if(p){if(!f.parent)continue;h=!1,p&&(t.target&&(i=!1),a=!0)}}return n&&(i&&!t.target&&!e.hitArea&&e.containsPoint&&e.containsPoint(s)&&(a=!0),e.interactive&&(a&&!t.target&&(t.target=e),r&&r(t,e,!!a))),a},t.prototype.findHit=function(t,e,r,i){this.recursiveFindHit(t,e,r,i,!1)},t}(),Hn={interactive:!1,interactiveChildren:!0,hitArea:null,get buttonMode(){return"pointer"===this.cursor},set buttonMode(t){t?this.cursor="pointer":"pointer"===this.cursor&&(this.cursor=null)},cursor:null,get trackedPointers(){return void 0===this._trackedPointers&&(this._trackedPointers={}),this._trackedPointers},_trackedPointers:void 0};Je.mixin(Hn);var Yn={target:null,data:{global:null}},Vn=function(e){function r(t,r){var i=e.call(this)||this;return r=r||{},i.renderer=t,i.autoPreventDefault=void 0===r.autoPreventDefault||r.autoPreventDefault,i.interactionFrequency=r.interactionFrequency||10,i.mouse=new Gn,i.mouse.identifier=1,i.mouse.global.set(-999999),i.activeInteractionData={},i.activeInteractionData[1]=i.mouse,i.interactionDataPool=[],i.eventData=new kn,i.interactionDOMElement=null,i.moveWhenInside=!1,i.eventsAdded=!1,i.tickerAdded=!1,i.mouseOverRenderer=!("PointerEvent"in globalThis),i.supportsTouchEvents="ontouchstart"in globalThis,i.supportsPointerEvents=!!globalThis.PointerEvent,i.onPointerUp=i.onPointerUp.bind(i),i.processPointerUp=i.processPointerUp.bind(i),i.onPointerCancel=i.onPointerCancel.bind(i),i.processPointerCancel=i.processPointerCancel.bind(i),i.onPointerDown=i.onPointerDown.bind(i),i.processPointerDown=i.processPointerDown.bind(i),i.onPointerMove=i.onPointerMove.bind(i),i.processPointerMove=i.processPointerMove.bind(i),i.onPointerOut=i.onPointerOut.bind(i),i.processPointerOverOut=i.processPointerOverOut.bind(i),i.onPointerOver=i.onPointerOver.bind(i),i.cursorStyles={default:"inherit",pointer:"pointer"},i.currentCursorMode=null,i.cursor=null,i.resolution=1,i.delayedEvents=[],i.search=new jn,i._tempDisplayObject=new $e,i._eventListenerOptions={capture:!0,passive:!1},i._useSystemTicker=void 0===r.useSystemTicker||r.useSystemTicker,i.setTargetElement(i.renderer.view,i.renderer.resolution),i}return function(t,e){function r(){this.constructor=t}Un(t,e),t.prototype=null===e?Object.create(e):(r.prototype=e.prototype,new r)}(r,e),Object.defineProperty(r.prototype,"useSystemTicker",{get:function(){return this._useSystemTicker},set:function(t){this._useSystemTicker=t,t?this.addTickerListener():this.removeTickerListener()},enumerable:!1,configurable:!0}),Object.defineProperty(r.prototype,"lastObjectRendered",{get:function(){return this.renderer._lastObjectRendered||this._tempDisplayObject},enumerable:!1,configurable:!0}),r.prototype.hitTest=function(t,e){return Yn.target=null,Yn.data.global=t,e||(e=this.lastObjectRendered),this.processInteractive(Yn,e,null,!0),Yn.target},r.prototype.setTargetElement=function(t,e){void 0===e&&(e=1),this.removeTickerListener(),this.removeEvents(),this.interactionDOMElement=t,this.resolution=e,this.addEvents(),this.addTickerListener()},r.prototype.addTickerListener=function(){!this.tickerAdded&&this.interactionDOMElement&&this._useSystemTicker&&(ar.system.add(this.tickerUpdate,this,t.UPDATE_PRIORITY.INTERACTION),this.tickerAdded=!0)},r.prototype.removeTickerListener=function(){this.tickerAdded&&(ar.system.remove(this.tickerUpdate,this),this.tickerAdded=!1)},r.prototype.addEvents=function(){if(!this.eventsAdded&&this.interactionDOMElement){var t=this.interactionDOMElement.style;globalThis.navigator.msPointerEnabled?(t.msContentZooming="none",t.msTouchAction="none"):this.supportsPointerEvents&&(t.touchAction="none"),this.supportsPointerEvents?(globalThis.document.addEventListener("pointermove",this.onPointerMove,this._eventListenerOptions),this.interactionDOMElement.addEventListener("pointerdown",this.onPointerDown,this._eventListenerOptions),this.interactionDOMElement.addEventListener("pointerleave",this.onPointerOut,this._eventListenerOptions),this.interactionDOMElement.addEventListener("pointerover",this.onPointerOver,this._eventListenerOptions),globalThis.addEventListener("pointercancel",this.onPointerCancel,this._eventListenerOptions),globalThis.addEventListener("pointerup",this.onPointerUp,this._eventListenerOptions)):(globalThis.document.addEventListener("mousemove",this.onPointerMove,this._eventListenerOptions),this.interactionDOMElement.addEventListener("mousedown",this.onPointerDown,this._eventListenerOptions),this.interactionDOMElement.addEventListener("mouseout",this.onPointerOut,this._eventListenerOptions),this.interactionDOMElement.addEventListener("mouseover",this.onPointerOver,this._eventListenerOptions),globalThis.addEventListener("mouseup",this.onPointerUp,this._eventListenerOptions)),this.supportsTouchEvents&&(this.interactionDOMElement.addEventListener("touchstart",this.onPointerDown,this._eventListenerOptions),this.interactionDOMElement.addEventListener("touchcancel",this.onPointerCancel,this._eventListenerOptions),this.interactionDOMElement.addEventListener("touchend",this.onPointerUp,this._eventListenerOptions),this.interactionDOMElement.addEventListener("touchmove",this.onPointerMove,this._eventListenerOptions)),this.eventsAdded=!0}},r.prototype.removeEvents=function(){if(this.eventsAdded&&this.interactionDOMElement){var t=this.interactionDOMElement.style;globalThis.navigator.msPointerEnabled?(t.msContentZooming="",t.msTouchAction=""):this.supportsPointerEvents&&(t.touchAction=""),this.supportsPointerEvents?(globalThis.document.removeEventListener("pointermove",this.onPointerMove,this._eventListenerOptions),this.interactionDOMElement.removeEventListener("pointerdown",this.onPointerDown,this._eventListenerOptions),this.interactionDOMElement.removeEventListener("pointerleave",this.onPointerOut,this._eventListenerOptions),this.interactionDOMElement.removeEventListener("pointerover",this.onPointerOver,this._eventListenerOptions),globalThis.removeEventListener("pointercancel",this.onPointerCancel,this._eventListenerOptions),globalThis.removeEventListener("pointerup",this.onPointerUp,this._eventListenerOptions)):(globalThis.document.removeEventListener("mousemove",this.onPointerMove,this._eventListenerOptions),this.interactionDOMElement.removeEventListener("mousedown",this.onPointerDown,this._eventListenerOptions),this.interactionDOMElement.removeEventListener("mouseout",this.onPointerOut,this._eventListenerOptions),this.interactionDOMElement.removeEventListener("mouseover",this.onPointerOver,this._eventListenerOptions),globalThis.removeEventListener("mouseup",this.onPointerUp,this._eventListenerOptions)),this.supportsTouchEvents&&(this.interactionDOMElement.removeEventListener("touchstart",this.onPointerDown,this._eventListenerOptions),this.interactionDOMElement.removeEventListener("touchcancel",this.onPointerCancel,this._eventListenerOptions),this.interactionDOMElement.removeEventListener("touchend",this.onPointerUp,this._eventListenerOptions),this.interactionDOMElement.removeEventListener("touchmove",this.onPointerMove,this._eventListenerOptions)),this.interactionDOMElement=null,this.eventsAdded=!1}},r.prototype.tickerUpdate=function(t){this._deltaTime+=t,this._deltaTime0&&(o=t.composedPath()[0]);for(var s=o!==this.interactionDOMElement?"outside":"",a=0;a=2?o.multisample:t.MSAA_QUALITY.NONE;if(n=this.renderer.generateTexture(e,{multisample:h}),h!==t.MSAA_QUALITY.NONE){var u=Fr.create({width:n.width,height:n.height});o.framebuffer.bind(n.framebuffer),o.framebuffer.blit(u.framebuffer),o.framebuffer.bind(null),n.destroy(!0),n=u}a=!0}n?(i=n.baseTexture.resolution,r=null!=r?r:n.frame,s=!1,o.renderTexture.bind(n)):(i=o.resolution,r||((r=zn).width=o.width,r.height=o.height),s=!0,o.renderTexture.bind(null));var l=Math.round(r.width*i),c=Math.round(r.height*i),d=new Uint8Array(4*l*c),f=o.gl;return f.readPixels(Math.round(r.x*i),Math.round(r.y*i),l,c,f.RGBA,f.UNSIGNED_BYTE,d),a&&n.destroy(!0),{pixels:d,width:l,height:c,flipY:s}},e.prototype.destroy=function(){this.renderer=null},e.arrayPostDivide=function(t,e){for(var r=0;r0||e.responseType===t.XHR_RESPONSE_TYPE.BUFFER)?i=200:1223===i&&(i=204),2==(i/100|0)){if(this.xhrType===t.XHR_RESPONSE_TYPE.TEXT)this.data=r,this.type=t.TYPE.TEXT;else if(this.xhrType===t.XHR_RESPONSE_TYPE.JSON)try{this.data=JSON.parse(r),this.type=t.TYPE.JSON}catch(t){return void this.abort("Error trying to parse loaded json: "+t)}else if(this.xhrType===t.XHR_RESPONSE_TYPE.DOCUMENT)try{if(globalThis.DOMParser){var n=new DOMParser;this.data=n.parseFromString(r,"text/xml")}else{var o=document.createElement("div");o.innerHTML=r,this.data=o}this.type=t.TYPE.XML}catch(t){return void this.abort("Error trying to parse loaded xml: "+t)}else this.data=e.response||r;this.complete()}else this.abort("["+e.status+"] "+e.statusText+": "+e.responseURL)},t.prototype._determineCrossOrigin=function(t,e){if(0===t.indexOf("data:"))return"";if(globalThis.origin!==globalThis.location.origin)return"anonymous";e=e||globalThis.location,$n||($n=document.createElement("a")),$n.href=t;var r=Jn($n.href,{strictMode:!0}),i=!r.port&&""===e.port||r.port===e.port,n=r.protocol?r.protocol+":":"";return r.host===e.hostname&&i&&n===e.protocol?"":"anonymous"},t.prototype._determineXhrType=function(){return t._xhrTypeMap[this.extension]||t.XHR_RESPONSE_TYPE.TEXT},t.prototype._determineLoadType=function(){return t._loadTypeMap[this.extension]||t.LOAD_TYPE.XHR},t.prototype._getExtension=function(t){void 0===t&&(t=this.url);var e="";if(this.isDataUrl){var r=t.indexOf("/");e=t.substring(r+1,t.indexOf(";",r))}else{var i=t.indexOf("?"),n=t.indexOf("#"),o=Math.min(i>-1?i:t.length,n>-1?n:t.length);e=(t=t.substring(0,o)).substring(t.lastIndexOf(".")+1)}return e.toLowerCase()},t.prototype._getMimeFromXhrType=function(e){switch(e){case t.XHR_RESPONSE_TYPE.BUFFER:return"application/octet-binary";case t.XHR_RESPONSE_TYPE.BLOB:return"application/blob";case t.XHR_RESPONSE_TYPE.DOCUMENT:return"application/xml";case t.XHR_RESPONSE_TYPE.JSON:return"application/json";case t.XHR_RESPONSE_TYPE.DEFAULT:case t.XHR_RESPONSE_TYPE.TEXT:default:return"text/plain"}},t}(),function(t){var e,r,i,n;(e=t.STATUS_FLAGS||(t.STATUS_FLAGS={}))[e.NONE=0]="NONE",e[e.DATA_URL=1]="DATA_URL",e[e.COMPLETE=2]="COMPLETE",e[e.LOADING=4]="LOADING",(r=t.TYPE||(t.TYPE={}))[r.UNKNOWN=0]="UNKNOWN",r[r.JSON=1]="JSON",r[r.XML=2]="XML",r[r.IMAGE=3]="IMAGE",r[r.AUDIO=4]="AUDIO",r[r.VIDEO=5]="VIDEO",r[r.TEXT=6]="TEXT",(i=t.LOAD_TYPE||(t.LOAD_TYPE={}))[i.XHR=1]="XHR",i[i.IMAGE=2]="IMAGE",i[i.AUDIO=3]="AUDIO",i[i.VIDEO=4]="VIDEO",(n=t.XHR_RESPONSE_TYPE||(t.XHR_RESPONSE_TYPE={})).DEFAULT="text",n.BUFFER="arraybuffer",n.BLOB="blob",n.DOCUMENT="document",n.JSON="json",n.TEXT="text",t._loadTypeMap={gif:t.LOAD_TYPE.IMAGE,png:t.LOAD_TYPE.IMAGE,bmp:t.LOAD_TYPE.IMAGE,jpg:t.LOAD_TYPE.IMAGE,jpeg:t.LOAD_TYPE.IMAGE,tif:t.LOAD_TYPE.IMAGE,tiff:t.LOAD_TYPE.IMAGE,webp:t.LOAD_TYPE.IMAGE,tga:t.LOAD_TYPE.IMAGE,avif:t.LOAD_TYPE.IMAGE,svg:t.LOAD_TYPE.IMAGE,"svg+xml":t.LOAD_TYPE.IMAGE,mp3:t.LOAD_TYPE.AUDIO,ogg:t.LOAD_TYPE.AUDIO,wav:t.LOAD_TYPE.AUDIO,mp4:t.LOAD_TYPE.VIDEO,webm:t.LOAD_TYPE.VIDEO},t._xhrTypeMap={xhtml:t.XHR_RESPONSE_TYPE.DOCUMENT,html:t.XHR_RESPONSE_TYPE.DOCUMENT,htm:t.XHR_RESPONSE_TYPE.DOCUMENT,xml:t.XHR_RESPONSE_TYPE.DOCUMENT,tmx:t.XHR_RESPONSE_TYPE.DOCUMENT,svg:t.XHR_RESPONSE_TYPE.DOCUMENT,tsx:t.XHR_RESPONSE_TYPE.DOCUMENT,gif:t.XHR_RESPONSE_TYPE.BLOB,png:t.XHR_RESPONSE_TYPE.BLOB,bmp:t.XHR_RESPONSE_TYPE.BLOB,jpg:t.XHR_RESPONSE_TYPE.BLOB,jpeg:t.XHR_RESPONSE_TYPE.BLOB,tif:t.XHR_RESPONSE_TYPE.BLOB,tiff:t.XHR_RESPONSE_TYPE.BLOB,webp:t.XHR_RESPONSE_TYPE.BLOB,tga:t.XHR_RESPONSE_TYPE.BLOB,avif:t.XHR_RESPONSE_TYPE.BLOB,json:t.XHR_RESPONSE_TYPE.JSON,text:t.XHR_RESPONSE_TYPE.TEXT,txt:t.XHR_RESPONSE_TYPE.TEXT,ttf:t.XHR_RESPONSE_TYPE.BUFFER,otf:t.XHR_RESPONSE_TYPE.BUFFER},t.EMPTY_GIF="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="}(t.LoaderResource||(t.LoaderResource={}));var oo=function(t,e){this.data=t,this.callback=e},so=function(){function t(t,e){var r=this;if(void 0===e&&(e=1),this.workers=0,this.saturated=io,this.unsaturated=io,this.empty=io,this.drain=io,this.error=io,this.started=!1,this.paused=!1,this._tasks=[],this._insert=function(t,e,i){if(i&&"function"!=typeof i)throw new Error("task callback must be a function");if(r.started=!0,null==t&&r.idle())setTimeout((function(){return r.drain()}),1);else{var n=new oo(t,"function"==typeof i?i:io);e?r._tasks.unshift(n):r._tasks.push(n),setTimeout(r.process,1)}},this.process=function(){for(;!r.paused&&r.workers>2,n[1]=(3&i[0])<<4|i[1]>>4,n[2]=(15&i[1])<<2|i[2]>>6,n[3]=63&i[2],r-(t.length-1)){case 2:n[3]=64,n[2]=64;break;case 1:n[3]=64}for(o=0;o0&&n[n.length-1])||6!==o[0]&&2!==o[0])){s=0;continue}if(3===o[0]&&(!n||o[1]>n[0]&&o[1]=33776&&t<=33779)return"s3tc";if(t>=37488&&t<=37497)return"etc";if(t>=35840&&t<=35843)return"pvrtc";if(t>=36196)return"etc1";if(t>=35986&&t<=34798)return"atc";throw new Error("Invalid (compressed) texture format given!")},e._createLevelBuffers=function(t,e,r,i,n,o,s){for(var a=new Array(r),h=t.byteOffset,u=o,l=s,c=u+i-1&~(i-1),d=l+n-1&~(n-1),f=c*d*_o[e],p=0;p1?u:c,levelHeight:r>1?l:d,levelBuffer:new Uint8Array(t.buffer,h,f)},h+=f,f=(c=(u=u>>1||1)+i-1&~(i-1))*(d=(l=l>>1||1)+n-1&~(n-1))*_o[e];return a},e}(To),bo=function(){function e(){}return e.use=function(r,i){var n=r.data;if(r.type===t.LoaderResource.TYPE.JSON&&n&&n.cacheID&&n.textures){for(var o=n.textures,s=void 0,a=void 0,h=0,u=o.length;h>>=1,E>>>=1;var x=148;for(b=0;b<_;b++)m.push(new Uint8Array(t,x,g)),x+=g}return m.map((function(t){return new Eo(t,{format:v,width:n,height:i,levels:o})}))}if(64&a)throw new Error("DDSParser does not support uncompressed texture data.");if(512&a)throw new Error("DDSParser does not supported YUV uncompressed texture data.");if(131072&a)throw new Error("DDSParser does not support single-channel (lumninance) texture data!");if(2&a)throw new Error("DDSParser does not support single-channel (alpha) texture data!");throw new Error("DDSParser failed to load a texture file due to an unknown reason!")}var wo=[171,75,84,88,32,49,49,187,13,10,26,10],Co=((Ro={})[t.TYPES.UNSIGNED_BYTE]=1,Ro[t.TYPES.UNSIGNED_SHORT]=2,Ro[t.TYPES.INT]=4,Ro[t.TYPES.UNSIGNED_INT]=4,Ro[t.TYPES.FLOAT]=4,Ro[t.TYPES.HALF_FLOAT]=8,Ro),No=((Oo={})[t.FORMATS.RGBA]=4,Oo[t.FORMATS.RGB]=3,Oo[t.FORMATS.RG]=2,Oo[t.FORMATS.RED]=1,Oo[t.FORMATS.LUMINANCE]=1,Oo[t.FORMATS.LUMINANCE_ALPHA]=2,Oo[t.FORMATS.ALPHA]=1,Oo),Fo=((Mo={})[t.TYPES.UNSIGNED_SHORT_4_4_4_4]=2,Mo[t.TYPES.UNSIGNED_SHORT_5_5_5_1]=2,Mo[t.TYPES.UNSIGNED_SHORT_5_6_5]=2,Mo);function Lo(e,r,i){void 0===i&&(i=!1);var n=new DataView(r);if(!function(t,e){for(var r=0;re-n){console.error("KTXLoader: keyAndValueByteSize out of bounds");break}for(var h=0;h1||0!==s?x:S,levelHeight:p>1||0!==s?A:R,levelBuffer:new Uint8Array(r,I,b)},I+=b}O=(O+=P+4)%4!=0?O+4-O%4:O,b=(S=(x=x>>1||1)+4-1&-4)*(R=(A=A>>1||1)+4-1&-4)*v}return 0!==s?{uncompressed:g.map((function(e){var r=e[0].levelBuffer,i=!1;return s===t.TYPES.FLOAT?r=new Float32Array(e[0].levelBuffer.buffer,e[0].levelBuffer.byteOffset,e[0].levelBuffer.byteLength/4):s===t.TYPES.UNSIGNED_INT?(i=!0,r=new Uint32Array(e[0].levelBuffer.buffer,e[0].levelBuffer.byteOffset,e[0].levelBuffer.byteLength/4)):s===t.TYPES.INT&&(i=!0,r=new Int32Array(e[0].levelBuffer.buffer,e[0].levelBuffer.byteOffset,e[0].levelBuffer.byteLength/4)),{resource:new _r(r,{width:e[0].levelWidth,height:e[0].levelHeight}),type:s,format:i?Bo(a):a}})),kvData:E}:{compressed:g.map((function(t){return new Eo(null,{format:h,width:u,height:l,levels:p,levelBuffers:t})})),kvData:E}}function Bo(e){switch(e){case t.FORMATS.RGBA:return t.FORMATS.RGBA_INTEGER;case t.FORMATS.RGB:return t.FORMATS.RGB_INTEGER;case t.FORMATS.RG:return t.FORMATS.RG_INTEGER;case t.FORMATS.RED:return t.FORMATS.RED_INTEGER;default:return e}}t.LoaderResource.setExtensionXhrType("dds",t.LoaderResource.XHR_RESPONSE_TYPE.BUFFER);var Go=function(){function e(){}return e.use=function(t,e){if("dds"===t.extension&&t.data)try{Object.assign(t,xo(t.name||t.url,Do(t.data),t.metadata))}catch(t){return void e(t)}e()},e.extension=t.ExtensionType.Loader,e}();t.LoaderResource.setExtensionXhrType("ktx",t.LoaderResource.XHR_RESPONSE_TYPE.BUFFER);var Uo=function(){function e(){}return e.use=function(e,r){if("ktx"===e.extension&&e.data)try{var i=e.name||e.url,n=Lo(0,e.data,this.loadKeyValueData),o=n.compressed,s=n.uncompressed,a=n.kvData;if(o){var h=xo(i,o,e.metadata);if(a&&h.textures)for(var u in h.textures)h.textures[u].baseTexture.ktxKeyValueData=a;Object.assign(e,h)}else if(s){var l={};s.forEach((function(e,r){var n=new Nr(new mr(e.resource,{mipmap:t.MIPMAP_MODES.OFF,alphaMode:t.ALPHA_MODES.NO_PREMULTIPLIED_ALPHA,type:e.type,format:e.format})),o=i+"-"+(r+1);a&&(n.baseTexture.ktxKeyValueData=a),mr.addToCache(n.baseTexture,o),Nr.addToCache(n,o),0===r&&(l[i]=n,mr.addToCache(n.baseTexture,i),Nr.addToCache(n,i)),l[o]=n})),Object.assign(e,{textures:l})}}catch(t){return void r(t)}r()},e.extension=t.ExtensionType.Loader,e.loadKeyValueData=!1,e}(),ko=function(t,e){return ko=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r])},ko(t,e)};function Xo(t,e){function r(){this.constructor=t}ko(t,e),t.prototype=null===e?Object.create(e):(r.prototype=e.prototype,new r)}var jo=function(e){function r(r,i,n,o){void 0===r&&(r=1500),void 0===n&&(n=16384),void 0===o&&(o=!1);var s=e.call(this)||this;return n>16384&&(n=16384),s._properties=[!1,!0,!1,!1,!1],s._maxSize=r,s._batchSize=n,s._buffers=null,s._bufferUpdateIDs=[],s._updateID=0,s.interactiveChildren=!1,s.blendMode=t.BLEND_MODES.NORMAL,s.autoResize=o,s.roundPixels=!0,s.baseTexture=null,s.setProperties(i),s._tint=0,s.tintRgb=new Float32Array(4),s.tint=16777215,s}return Xo(r,e),r.prototype.setProperties=function(t){t&&(this._properties[0]="vertices"in t||"scale"in t?!!t.vertices||!!t.scale:this._properties[0],this._properties[1]="position"in t?!!t.position:this._properties[1],this._properties[2]="rotation"in t?!!t.rotation:this._properties[2],this._properties[3]="uvs"in t?!!t.uvs:this._properties[3],this._properties[4]="tint"in t||"alpha"in t?!!t.tint||!!t.alpha:this._properties[4])},r.prototype.updateTransform=function(){this.displayObjectUpdateTransform()},Object.defineProperty(r.prototype,"tint",{get:function(){return this._tint},set:function(t){this._tint=t,$t(t,this.tintRgb)},enumerable:!1,configurable:!0}),r.prototype.render=function(t){var e=this;this.visible&&!(this.worldAlpha<=0)&&this.children.length&&this.renderable&&(this.baseTexture||(this.baseTexture=this.children[0]._texture.baseTexture,this.baseTexture.valid||this.baseTexture.once("update",(function(){return e.onChildrenChange(0)}))),t.batch.setObjectRenderer(t.plugins.particle),t.plugins.particle.render(this))},r.prototype.onChildrenChange=function(t){for(var e=Math.floor(t/this._batchSize);this._bufferUpdateIDs.lengthr&&!t.autoResize&&(o=r);var s=t._buffers;s||(s=t._buffers=this.generateBuffers(t));var a=e[0]._texture.baseTexture,h=a.alphaMode>0;this.state.blendMode=ie(t.blendMode,h),n.state.set(this.state);var u=n.gl,l=t.worldTransform.copyTo(this.tempMatrix);l.prepend(n.globalUniforms.uniforms.projectionMatrix),this.shader.uniforms.translationMatrix=l.toArray(!0),this.shader.uniforms.uColor=ne(t.tintRgb,t.worldAlpha,this.shader.uniforms.uColor,h),this.shader.uniforms.uSampler=a,this.renderer.shader.bind(this.shader);for(var c=!1,d=0,f=0;di&&(p=i),f>=s.length&&s.push(this._generateOneMoreBuffer(t));var _=s[f];_.uploadDynamic(e,d,p);var v=t._bufferUpdateIDs[f]||0;(c=c||_._updateID0,u=a.alpha,l=u<1&&h?oe(a._tintRGB,u):a._tintRGB+(255*u<<24);i[o]=l,i[o+n]=l,i[o+2*n]=l,i[o+3*n]=l,o+=4*n}},r.prototype.destroy=function(){e.prototype.destroy.call(this),this.shader&&(this.shader.destroy(),this.shader=null),this.tempMatrix=null},r.extension={name:"particle",type:t.ExtensionType.RendererPlugin},r}($r);t.LINE_JOIN=void 0,t.LINE_CAP=void 0,function(t){t.MITER="miter",t.BEVEL="bevel",t.ROUND="round"}(t.LINE_JOIN||(t.LINE_JOIN={})),function(t){t.BUTT="butt",t.ROUND="round",t.SQUARE="square"}(t.LINE_CAP||(t.LINE_CAP={}));var Vo={adaptive:!0,maxLength:10,minSegments:8,maxSegments:2048,epsilon:1e-4,_segmentsCount:function(t,e){if(void 0===e&&(e=20),!this.adaptive||!t||isNaN(t))return e;var r=Math.ceil(t/this.maxLength);return rthis.maxSegments&&(r=this.maxSegments),r}},zo=function(){function t(){this.color=16777215,this.alpha=1,this.texture=Nr.WHITE,this.matrix=null,this.visible=!1,this.reset()}return t.prototype.clone=function(){var e=new t;return e.color=this.color,e.alpha=this.alpha,e.texture=this.texture,e.matrix=this.matrix,e.visible=this.visible,e},t.prototype.reset=function(){this.color=16777215,this.alpha=1,this.texture=Nr.WHITE,this.matrix=null,this.visible=!1},t.prototype.destroy=function(){this.texture=null,this.matrix=null},t}(),Wo=function(t,e){return Wo=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r])},Wo(t,e)};function qo(t,e){function r(){this.constructor=t}Wo(t,e),t.prototype=null===e?Object.create(e):(r.prototype=e.prototype,new r)}function Ko(t,e){var r,i;void 0===e&&(e=!1);var n=t.length;if(!(n<6)){for(var o=0,s=0,a=t[n-2],h=t[n-1];s0||e&&o<=0){var c=n/2;for(s=c+c%2;s=6){Ko(r,!1);for(var s=[],a=0;a=0&&a>=0&&n>=0&&o>=0){var p=Math.ceil(2.3*Math.sqrt(s+a)),_=8*p+(n?4:0)+(o?4:0);if(h.length=_,0!==_){if(0===p)return h.length=8,h[0]=h[6]=r+n,h[1]=h[3]=i+o,h[2]=h[4]=r-n,void(h[5]=h[7]=i-o);var v,m,y=0,g=4*p+(n?2:0)+2,T=g,E=_,b=r+(v=n+s),x=r-v,A=i+(m=o);if(h[y++]=b,h[y++]=A,h[--g]=A,h[--g]=x,o){var S=i-m;h[T++]=x,h[T++]=S,h[--E]=S,h[--E]=b}for(var R=1;Rc&&(c+=2*Math.PI);var d=l,f=c-l,p=Math.abs(f),_=Math.sqrt(h*h+u*u),v=1+(15*p*Math.sqrt(_)/Math.PI>>0),m=f/v;if(d+=m,a){s.push(t,e),s.push(r,i);for(var y=1,g=d;y=0&&(s.join===t.LINE_JOIN.ROUND?_+=is(b,x,b-R*w,x-O*w,b-M*w,x-P*w,f,!1)+4:_+=2,f.push(b-M*C,x-P*C),f.push(b+M*w,x+P*w));else{var j=(-R+T)*(-O+x)-(-R+b)*(-O+E),H=(-M+A)*(-P+x)-(-M+b)*(-P+S),Y=(F*H-B*j)/k,V=(G*j-L*H)/k,z=(Y-b)*(Y-b)+(V-x)*(V-x),W=b+(Y-b)*w,q=x+(V-x)*w,K=b-(Y-b)*C,Z=x-(V-x)*C,Q=X?w:C;z<=Math.min(F*F+L*L,B*B+G*G)+Q*Q*y?s.join===t.LINE_JOIN.BEVEL||z/y>g?(X?(f.push(W,q),f.push(b+R*C,x+O*C),f.push(W,q),f.push(b+M*C,x+P*C)):(f.push(b-R*w,x-O*w),f.push(K,Z),f.push(b-M*w,x-P*w),f.push(K,Z)),_+=2):s.join===t.LINE_JOIN.ROUND?X?(f.push(W,q),f.push(b+R*C,x+O*C),_+=is(b,x,b+R*C,x+O*C,b+M*C,x+P*C,f,!0)+4,f.push(W,q),f.push(b+M*C,x+P*C)):(f.push(b-R*w,x-O*w),f.push(K,Z),_+=is(b,x,b-R*w,x-O*w,b-M*w,x-P*w,f,!1)+4,f.push(b-M*w,x-P*w),f.push(K,Z)):(f.push(W,q),f.push(K,Z)):(f.push(b-R*w,x-O*w),f.push(b+R*C,x+O*C),s.join===t.LINE_JOIN.ROUND?_+=X?is(b,x,b+R*C,x+O*C,b+M*C,x+P*C,f,!0)+2:is(b,x,b-R*w,x-O*w,b-M*w,x-P*w,f,!1)+2:s.join===t.LINE_JOIN.MITER&&z/y<=g&&(X?(f.push(K,Z),f.push(K,Z)):(f.push(W,q),f.push(W,q)),_+=2),f.push(b-M*w,x-P*w),f.push(b+M*C,x+P*C),_+=2)}}T=n[2*(p-2)],E=n[2*(p-2)+1],b=n[2*(p-1)],R=-(E-(x=n[2*(p-1)+1])),O=T-b,R/=I=Math.sqrt(R*R+O*O),O/=I,R*=m,O*=m,f.push(b-R*w,x-O*w),f.push(b+R*C,x+O*C),u||(s.cap===t.LINE_CAP.ROUND?_+=is(b-R*(w-C)*.5,x-O*(w-C)*.5,b-R*w,x-O*w,b+R*C,x+O*C,f,!1)+2:s.cap===t.LINE_CAP.SQUARE&&(_+=rs(b,x,R,O,w,C,!1,f)));var J=r.indices,$=Vo.epsilon*Vo.epsilon;for(N=v;N<_+v-2;++N)T=f[2*N],E=f[2*N+1],b=f[2*(N+1)],x=f[2*(N+1)+1],A=f[2*(N+2)],S=f[2*(N+2)+1],Math.abs(T*(x-S)+b*(S-E)+A*(E-x))<$||J.push(N,N+1,N+2)}}(e,r)}var os,ss=function(){function t(){}return t.curveTo=function(t,e,r,i,n,o){var s=o[o.length-2],a=o[o.length-1]-e,h=s-t,u=i-e,l=r-t,c=Math.abs(a*l-h*u);if(c<1e-8||0===n)return o[o.length-2]===t&&o[o.length-1]===e||o.push(t,e),null;var d=a*a+h*h,f=u*u+l*l,p=a*u+h*l,_=n*Math.sqrt(d)/c,v=n*Math.sqrt(f)/c,m=_*p/d,y=v*p/f,g=_*l+v*h,T=_*u+v*a,E=h*(v+m),b=a*(v+m),x=l*(_+y),A=u*(_+y);return{cx:g+t,cy:T+e,radius:n,startAngle:Math.atan2(b-T,E-g),endAngle:Math.atan2(A-T,x-g),anticlockwise:h*u>l*a}},t.arc=function(t,e,r,i,n,o,s,a,h){for(var u=s-o,l=Vo._segmentsCount(Math.abs(u)*n,40*Math.ceil(Math.abs(u)/Me)),c=u/(2*l),d=2*c,f=Math.cos(c),p=Math.sin(c),_=l-1,v=_%1/_,m=0;m<=_;++m){var y=c+o+d*(m+v*m),g=Math.cos(y),T=-Math.sin(y);h.push((f*g+p*T)*n+r,(f*-T+p*g)*n+i)}},t}(),as=function(){function t(){}return t.curveLength=function(t,e,r,i,n,o,s,a){for(var h=0,u=0,l=0,c=0,d=0,f=0,p=0,_=0,v=0,m=0,y=0,g=t,T=e,E=1;E<=10;++E)m=g-(_=(p=(f=(d=1-(u=E/10))*d)*d)*t+3*f*u*r+3*d*(l=u*u)*n+(c=l*u)*s),y=T-(v=p*e+3*f*u*i+3*d*l*o+c*a),g=_,T=v,h+=Math.sqrt(m*m+y*y);return h},t.curveTo=function(e,r,i,n,o,s,a){var h=a[a.length-2],u=a[a.length-1];a.length-=2;var l=Vo._segmentsCount(t.curveLength(h,u,e,r,i,n,o,s)),c=0,d=0,f=0,p=0,_=0;a.push(h,u);for(var v=1,m=0;v<=l;++v)f=(d=(c=1-(m=v/l))*c)*c,_=(p=m*m)*m,a.push(f*h+3*d*m*e+3*c*p*i+_*o,f*u+3*d*m*r+3*c*p*n+_*s)},t}(),hs=function(){function t(){}return t.curveLength=function(t,e,r,i,n,o){var s=t-2*r+n,a=e-2*i+o,h=2*r-2*t,u=2*i-2*e,l=4*(s*s+a*a),c=4*(s*h+a*u),d=h*h+u*u,f=2*Math.sqrt(l+c+d),p=Math.sqrt(l),_=2*l*p,v=2*Math.sqrt(d),m=c/p;return(_*f+p*c*(f-v)+(4*d*l-c*c)*Math.log((2*p+m+f)/(m+v)))/(4*_)},t.curveTo=function(e,r,i,n,o){for(var s=o[o.length-2],a=o[o.length-1],h=Vo._segmentsCount(t.curveLength(s,a,e,r,i,n)),u=0,l=0,c=1;c<=h;++c){var d=c/h;u=s+(e-s)*d,l=a+(r-a)*d,o.push(u+(e+(i-e)*d-u)*d,l+(r+(n-r)*d-l)*d)}},t}(),us=function(){function t(){this.reset()}return t.prototype.begin=function(t,e,r){this.reset(),this.style=t,this.start=e,this.attribStart=r},t.prototype.end=function(t,e){this.attribSize=e-this.attribStart,this.size=t-this.start},t.prototype.reset=function(){this.style=null,this.size=0,this.start=0,this.attribStart=0,this.attribSize=0},t}(),ls=((os={})[t.SHAPES.POLY]=Zo,os[t.SHAPES.CIRC]=Qo,os[t.SHAPES.ELIP]=Qo,os[t.SHAPES.RECT]=Jo,os[t.SHAPES.RREC]=es,os),cs=[],ds=[],fs=function(){function t(t,e,r,i){void 0===e&&(e=null),void 0===r&&(r=null),void 0===i&&(i=null),this.points=[],this.holes=[],this.shape=t,this.lineStyle=r,this.fillStyle=e,this.matrix=i,this.type=t.type}return t.prototype.clone=function(){return new t(this.shape,this.fillStyle,this.lineStyle,this.matrix)},t.prototype.destroy=function(){this.shape=null,this.holes.length=0,this.holes=null,this.points.length=0,this.points=null,this.lineStyle=null,this.fillStyle=null},t}(),ps=new De,_s=function(e){function r(){var t=e.call(this)||this;return t.closePointEps=1e-4,t.boundsPadding=0,t.uvsFloat32=null,t.indicesUint16=null,t.batchable=!1,t.points=[],t.colors=[],t.uvs=[],t.indices=[],t.textureIds=[],t.graphicsData=[],t.drawCalls=[],t.batchDirty=-1,t.batches=[],t.dirty=0,t.cacheDirty=-1,t.clearDirty=0,t.shapeIndex=0,t._bounds=new Ke,t.boundsDirty=-1,t}return qo(r,e),Object.defineProperty(r.prototype,"bounds",{get:function(){return this.updateBatches(),this.boundsDirty!==this.dirty&&(this.boundsDirty=this.dirty,this.calculateBounds()),this._bounds},enumerable:!1,configurable:!0}),r.prototype.invalidate=function(){this.boundsDirty=-1,this.dirty++,this.batchDirty++,this.shapeIndex=0,this.points.length=0,this.colors.length=0,this.uvs.length=0,this.indices.length=0,this.textureIds.length=0;for(var t=0;t0&&(this.invalidate(),this.clearDirty++,this.graphicsData.length=0),this},r.prototype.drawShape=function(t,e,r,i){void 0===e&&(e=null),void 0===r&&(r=null),void 0===i&&(i=null);var n=new fs(t,e,r,i);return this.graphicsData.push(n),this.dirty++,this},r.prototype.drawHole=function(t,e){if(void 0===e&&(e=null),!this.graphicsData.length)return null;var r=new fs(t,null,null,e),i=this.graphicsData[this.graphicsData.length-1];return r.lineStyle=i.lineStyle,i.holes.push(r),this.dirty++,this},r.prototype.destroy=function(){e.prototype.destroy.call(this);for(var t=0;t0&&(n=(i=this.batches[this.batches.length-1]).style);for(var o=this.shapeIndex;o65535;this.indicesUint16&&this.indices.length===this.indicesUint16.length&&m===this.indicesUint16.BYTES_PER_ELEMENT>2?this.indicesUint16.set(this.indices):this.indicesUint16=m?new Uint32Array(this.indices):new Uint16Array(this.indices),this.batchable=this.isBatchable(),this.batchable?this.packBatches():this.buildDrawCalls()}else this.batchable=!0}}else this.batchable=!0},r.prototype._compareStyles=function(t,e){return!(!t||!e)&&t.texture.baseTexture===e.texture.baseTexture&&t.color+t.alpha===e.color+e.alpha&&!!t.native==!!e.native},r.prototype.validateBatching=function(){if(this.dirty===this.cacheDirty||!this.graphicsData.length)return!1;for(var t=0,e=this.graphicsData.length;t131070)return!1;for(var t=this.batches,e=0;e0&&((o=ds.pop())||((o=new En).texArray=new bn),this.drawCalls.push(o)),o.start=c,o.size=0,o.texArray.count=0,o.type=l),p.touched=1,p._batchEnabled=e,p._batchLocation=s,p.wrapMode=t.WRAP_MODES.REPEAT,o.texArray.elements[o.texArray.count++]=p,s++)),o.size+=d.size,c+=d.size,h=p._batchLocation,this.addColors(i,f.color,f.alpha,d.attribSize,d.attribStart),this.addTextureIds(n,h,d.attribSize,d.attribStart)}mr._globalBatch=e,this.packAttributes()},r.prototype.packAttributes=function(){for(var t=this.points,e=this.uvs,r=this.colors,i=this.textureIds,n=new ArrayBuffer(3*t.length*4),o=new Float32Array(n),s=new Uint32Array(n),a=0,h=0;h>16)+(65280&e)+((255&e)<<16),r);t.length=Math.max(t.length,n+i);for(var s=0;s0&&e.alpha>0;return r?(e.matrix&&(e.matrix=e.matrix.clone(),e.matrix.invert()),Object.assign(this._lineStyle,{visible:r},e)):this._lineStyle.reset(),this},r.prototype.startPoly=function(){if(this.currentPath){var t=this.currentPath.points,e=this.currentPath.points.length;e>2&&(this.drawShape(this.currentPath),this.currentPath=new Le,this.currentPath.closeStroke=!1,this.currentPath.points.push(t[e-2],t[e-1]))}else this.currentPath=new Le,this.currentPath.closeStroke=!1},r.prototype.finishPoly=function(){this.currentPath&&(this.currentPath.points.length>2?(this.drawShape(this.currentPath),this.currentPath=null):this.currentPath.points.length=0)},r.prototype.moveTo=function(t,e){return this.startPoly(),this.currentPath.points[0]=t,this.currentPath.points[1]=e,this},r.prototype.lineTo=function(t,e){this.currentPath||this.moveTo(0,0);var r=this.currentPath.points,i=r[r.length-2],n=r[r.length-1];return i===t&&n===e||r.push(t,e),this},r.prototype._initCurve=function(t,e){void 0===t&&(t=0),void 0===e&&(e=0),this.currentPath?0===this.currentPath.points.length&&(this.currentPath.points=[t,e]):this.moveTo(t,e)},r.prototype.quadraticCurveTo=function(t,e,r,i){this._initCurve();var n=this.currentPath.points;return 0===n.length&&this.moveTo(0,0),hs.curveTo(t,e,r,i,n),this},r.prototype.bezierCurveTo=function(t,e,r,i,n,o){return this._initCurve(),as.curveTo(t,e,r,i,n,o,this.currentPath.points),this},r.prototype.arcTo=function(t,e,r,i,n){this._initCurve(t,e);var o=this.currentPath.points,s=ss.curveTo(t,e,r,i,n,o);if(s){var a=s.cx,h=s.cy,u=s.radius,l=s.startAngle,c=s.endAngle,d=s.anticlockwise;this.arc(a,h,u,l,c,d)}return this},r.prototype.arc=function(t,e,r,i,n,o){if(void 0===o&&(o=!1),i===n)return this;if(!o&&n<=i?n+=Me:o&&i<=n&&(i+=Me),0==n-i)return this;var s=t+Math.cos(i)*r,a=e+Math.sin(i)*r,h=this._geometry.closePointEps,u=this.currentPath?this.currentPath.points:null;if(u){var l=Math.abs(u[u.length-2]-s),c=Math.abs(u[u.length-1]-a);l0;return e?(t.matrix&&(t.matrix=t.matrix.clone(),t.matrix.invert()),Object.assign(this._fillStyle,{visible:e},t)):this._fillStyle.reset(),this},r.prototype.endFill=function(){return this.finishPoly(),this._fillStyle.reset(),this},r.prototype.drawRect=function(t,e,r,i){return this.drawShape(new Ce(t,e,r,i))},r.prototype.drawRoundedRect=function(t,e,r,i,n){return this.drawShape(new Be(t,e,r,i,n))},r.prototype.drawCircle=function(t,e,r){return this.drawShape(new Ne(t,e,r))},r.prototype.drawEllipse=function(t,e,r,i){return this.drawShape(new Fe(t,e,r,i))},r.prototype.drawPolygon=function(){for(var t,e=arguments,r=[],i=0;i>16&255)/255*n,o.tint[1]=(i>>8&255)/255*n,o.tint[2]=(255&i)/255*n,o.tint[3]=n,t.shader.bind(e),t.geometry.bind(r,e),t.state.set(this.state);for(var a=0,h=s.length;a>16)+(65280&n)+((255&n)<<16)}}},r.prototype.calculateVertices=function(){var t=this.transform._worldID;if(this._transformID!==t){this._transformID=t;for(var e=this.transform.worldTransform,r=e.a,i=e.b,n=e.c,o=e.d,s=e.tx,a=e.ty,h=this._geometry.points,u=this.vertexData,l=0,c=0;c=i&&bs.x=n&&bs.y>16)+(65280&t)+((255&t)<<16)},enumerable:!1,configurable:!0}),Object.defineProperty(r.prototype,"texture",{get:function(){return this._texture},set:function(t){this._texture!==t&&(this._texture&&this._texture.off("update",this._onTextureUpdate,this),this._texture=t||Nr.EMPTY,this._cachedTint=16777215,this._textureID=-1,this._textureTrimmedID=-1,t&&(t.baseTexture.valid?this._onTextureUpdate():t.once("update",this._onTextureUpdate,this)))},enumerable:!1,configurable:!0}),r}(er);t.TEXT_GRADIENT=void 0;var Ss=function(t,e){return Ss=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r])},Ss(t,e)};!function(t){t[t.LINEAR_VERTICAL=0]="LINEAR_VERTICAL",t[t.LINEAR_HORIZONTAL=1]="LINEAR_HORIZONTAL"}(t.TEXT_GRADIENT||(t.TEXT_GRADIENT={}));var Rs={align:"left",breakWords:!1,dropShadow:!1,dropShadowAlpha:1,dropShadowAngle:Math.PI/6,dropShadowBlur:0,dropShadowColor:"black",dropShadowDistance:5,fill:"black",fillGradientType:t.TEXT_GRADIENT.LINEAR_VERTICAL,fillGradientStops:[],fontFamily:"Arial",fontSize:26,fontStyle:"normal",fontVariant:"normal",fontWeight:"normal",letterSpacing:0,lineHeight:0,lineJoin:"miter",miterLimit:10,padding:0,stroke:"black",strokeThickness:0,textBaseline:"alphabetic",trim:!1,whiteSpace:"pre",wordWrap:!1,wordWrapWidth:100,leading:0},Os=["serif","sans-serif","monospace","cursive","fantasy","system-ui"],Ms=function(){function t(t){this.styleID=0,this.reset(),Ds(this,t,t)}return t.prototype.clone=function(){var e={};return Ds(e,this,Rs),new t(e)},t.prototype.reset=function(){Ds(this,Rs,Rs)},Object.defineProperty(t.prototype,"align",{get:function(){return this._align},set:function(t){this._align!==t&&(this._align=t,this.styleID++)},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"breakWords",{get:function(){return this._breakWords},set:function(t){this._breakWords!==t&&(this._breakWords=t,this.styleID++)},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"dropShadow",{get:function(){return this._dropShadow},set:function(t){this._dropShadow!==t&&(this._dropShadow=t,this.styleID++)},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"dropShadowAlpha",{get:function(){return this._dropShadowAlpha},set:function(t){this._dropShadowAlpha!==t&&(this._dropShadowAlpha=t,this.styleID++)},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"dropShadowAngle",{get:function(){return this._dropShadowAngle},set:function(t){this._dropShadowAngle!==t&&(this._dropShadowAngle=t,this.styleID++)},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"dropShadowBlur",{get:function(){return this._dropShadowBlur},set:function(t){this._dropShadowBlur!==t&&(this._dropShadowBlur=t,this.styleID++)},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"dropShadowColor",{get:function(){return this._dropShadowColor},set:function(t){var e=Is(t);this._dropShadowColor!==e&&(this._dropShadowColor=e,this.styleID++)},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"dropShadowDistance",{get:function(){return this._dropShadowDistance},set:function(t){this._dropShadowDistance!==t&&(this._dropShadowDistance=t,this.styleID++)},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"fill",{get:function(){return this._fill},set:function(t){var e=Is(t);this._fill!==e&&(this._fill=e,this.styleID++)},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"fillGradientType",{get:function(){return this._fillGradientType},set:function(t){this._fillGradientType!==t&&(this._fillGradientType=t,this.styleID++)},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"fillGradientStops",{get:function(){return this._fillGradientStops},set:function(t){(function(t,e){if(!Array.isArray(t)||!Array.isArray(e))return!1;if(t.length!==e.length)return!1;for(var r=0;r=0;r--){var i=e[r].trim();!/([\"\'])[^\'\"]+\1/.test(i)&&Os.indexOf(i)<0&&(i='"'+i+'"'),e[r]=i}return this.fontStyle+" "+this.fontVariant+" "+this.fontWeight+" "+t+" "+e.join(",")},t}();function Ps(t){return"number"==typeof t?te(t):("string"==typeof t&&0===t.indexOf("0x")&&(t=t.replace("0x","#")),t)}function Is(t){if(Array.isArray(t)){for(var e=0;ep)if(""!==s&&(a+=t.addLine(s),s="",o=0),t.canBreakWords(m,r.breakWords))for(var E=t.wordWrapSplit(m),b=0;bp&&(a+=t.addLine(s),f=!1,s="",o=0),s+=x,o+=O}else{s.length>0&&(a+=t.addLine(s),s="",o=0);var M=v===_.length-1;a+=t.addLine(m,!M),f=!1,s="",o=0}else T+o>p&&(f=!1,a+=t.addLine(s),s="",o=0),(s.length>0||!t.isBreakingSpace(m)||f)&&(s+=m,o+=T)}return a+t.addLine(s,!1)},t.addLine=function(e,r){return void 0===r&&(r=!0),e=t.trimRight(e),r?e+"\n":e},t.getFromCache=function(t,e,r,i){var n=r[t];if("number"!=typeof n){var o=t.length*e;n=i.measureText(t).width+o,r[t]=n}return n},t.collapseSpaces=function(t){return"normal"===t||"pre-line"===t},t.collapseNewlines=function(t){return"normal"===t},t.trimRight=function(e){if("string"!=typeof e)return"";for(var r=e.length-1;r>=0;r--){var i=e[r];if(!t.isBreakingSpace(i))break;e=e.slice(0,-1)}return e},t.isNewline=function(e){return"string"==typeof e&&t._newlines.indexOf(e.charCodeAt(0))>=0},t.isBreakingSpace=function(e,r){return"string"==typeof e&&t._breakingSpaces.indexOf(e.charCodeAt(0))>=0},t.tokenize=function(e){var r=[],i="";if("string"!=typeof e)return r;for(var n=0;na;--d){for(_=0;_0&&_>v&&(m=(v+_)/2);var y=v+p,g=i.lineHeight*(f+1),T=y;f+10},t}();function Gs(t,e){var r=!1;if(t&&t._textures&&t._textures.length)for(var i=0;i=0;e--)this.add(t.children[e]);return this},e.prototype.destroy=function(){this.ticking&&ar.system.remove(this.tick,this),this.ticking=!1,this.addHooks=null,this.uploadHooks=null,this.renderer=null,this.completes=null,this.queue=null,this.limiter=null,this.uploadHookHelper=null},e}();function zs(t,e){return e instanceof mr&&(e._glTextures[t.CONTEXT_UID]||t.texture.bind(e),!0)}function Ws(t,e){if(!(e instanceof gs))return!1;var r=e.geometry;e.finishPoly(),r.updateBatches();for(var i=r.batches,n=0;n=i&&ea.x=n&&ea.y1?Ci.from("#version 300 es\n#define SHADER_NAME Tiling-Sprite-300\n\nprecision lowp float;\n\nin vec2 aVertexPosition;\nin vec2 aTextureCoord;\n\nuniform mat3 projectionMatrix;\nuniform mat3 translationMatrix;\nuniform mat3 uTransform;\n\nout vec2 vTextureCoord;\n\nvoid main(void)\n{\n gl_Position = vec4((projectionMatrix * translationMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);\n\n vTextureCoord = (uTransform * vec3(aTextureCoord, 1.0)).xy;\n}\n","#version 300 es\n#define SHADER_NAME Tiling-Sprite-100\n\nprecision lowp float;\n\nin vec2 vTextureCoord;\n\nout vec4 fragmentColor;\n\nuniform sampler2D uSampler;\nuniform vec4 uColor;\nuniform mat3 uMapCoord;\nuniform vec4 uClampFrame;\nuniform vec2 uClampOffset;\n\nvoid main(void)\n{\n vec2 coord = vTextureCoord + ceil(uClampOffset - vTextureCoord);\n coord = (uMapCoord * vec3(coord, 1.0)).xy;\n vec2 unclamped = coord;\n coord = clamp(coord, uClampFrame.xy, uClampFrame.zw);\n\n vec4 texSample = texture(uSampler, coord, unclamped == coord ? 0.0f : -32.0f);// lod-bias very negative to force lod 0\n\n fragmentColor = texSample * uColor;\n}\n",e):Ci.from(ia,"#version 100\n#ifdef GL_EXT_shader_texture_lod\n #extension GL_EXT_shader_texture_lod : enable\n#endif\n#define SHADER_NAME Tiling-Sprite-100\n\nprecision lowp float;\n\nvarying vec2 vTextureCoord;\n\nuniform sampler2D uSampler;\nuniform vec4 uColor;\nuniform mat3 uMapCoord;\nuniform vec4 uClampFrame;\nuniform vec2 uClampOffset;\n\nvoid main(void)\n{\n vec2 coord = vTextureCoord + ceil(uClampOffset - vTextureCoord);\n coord = (uMapCoord * vec3(coord, 1.0)).xy;\n vec2 unclamped = coord;\n coord = clamp(coord, uClampFrame.xy, uClampFrame.zw);\n\n #ifdef GL_EXT_shader_texture_lod\n vec4 texSample = unclamped == coord\n ? texture2D(uSampler, coord) \n : texture2DLodEXT(uSampler, coord, 0);\n #else\n vec4 texSample = texture2D(uSampler, coord);\n #endif\n\n gl_FragColor = texSample * uColor;\n}\n",e)},r.prototype.render=function(e){var r=this.renderer,i=this.quad,n=i.vertices;n[0]=n[6]=e._width*-e.anchor.x,n[1]=n[3]=e._height*-e.anchor.y,n[2]=n[4]=e._width*(1-e.anchor.x),n[5]=n[7]=e._height*(1-e.anchor.y);var o=e.uvRespectAnchor?e.anchor.x:0,s=e.uvRespectAnchor?e.anchor.y:0;(n=i.uvs)[0]=n[6]=-o,n[1]=n[3]=-s,n[2]=n[4]=1-o,n[5]=n[7]=1-s,i.invalidate();var a=e._texture,h=a.baseTexture,u=h.alphaMode>0,l=e.tileTransform.localTransform,c=e.uvMatrix,d=h.isPowerOfTwo&&a.frame.width===h.width&&a.frame.height===h.height;d&&(h._glTextures[r.CONTEXT_UID]?d=h.wrapMode!==t.WRAP_MODES.CLAMP:h.wrapMode===t.WRAP_MODES.CLAMP&&(h.wrapMode=t.WRAP_MODES.REPEAT));var f=d?this.simpleShader:this.shader,p=a.width,_=a.height,v=e._width,m=e._height;na.set(l.a*p/v,l.b*p/m,l.c*_/v,l.d*_/m,l.tx/v,l.ty/m),na.invert(),d?na.prepend(c.mapCoord):(f.uniforms.uMapCoord=c.mapCoord.toArray(!0),f.uniforms.uClampFrame=c.uClampFrame,f.uniforms.uClampOffset=c.uClampOffset),f.uniforms.uTransform=na.toArray(!0),f.uniforms.uColor=se(e.tint,e.worldAlpha,f.uniforms.uColor,u),f.uniforms.translationMatrix=e.transform.worldTransform.toArray(!0),f.uniforms.uSampler=a,r.shader.bind(f),r.geometry.bind(i),this.state.blendMode=ie(e.blendMode,u),r.state.set(this.state),r.geometry.draw(this.renderer.gl.TRIANGLES,6,0)},r.extension={name:"tilingSprite",type:t.ExtensionType.RendererPlugin},r}($r),sa=function(t,e){return sa=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r])},sa(t,e)};function aa(t,e){function r(){this.constructor=t}sa(t,e),t.prototype=null===e?Object.create(e):(r.prototype=e.prototype,new r)}var ha=function(){function t(t,e){this.uvBuffer=t,this.uvMatrix=e,this.data=null,this._bufferUpdateId=-1,this._textureUpdateId=-1,this._updateID=0}return t.prototype.update=function(t){if(t||this._bufferUpdateId!==this.uvBuffer._updateID||this._textureUpdateId!==this.uvMatrix._updateID){this._bufferUpdateId=this.uvBuffer._updateID,this._textureUpdateId=this.uvMatrix._updateID;var e=this.uvBuffer.data;this.data&&this.data.length===e.length||(this.data=new Float32Array(e.length)),this.uvMatrix.multiplyUvs(e,this.data),this._updateID++}},t}(),ua=new De,la=new Le,ca=function(e){function r(r,i,n,o){void 0===o&&(o=t.DRAW_MODES.TRIANGLES);var s=e.call(this)||this;return s.geometry=r,s.shader=i,s.state=n||Ni.for2d(),s.drawMode=o,s.start=0,s.size=0,s.uvs=null,s.indices=null,s.vertexData=new Float32Array(1),s.vertexDirty=-1,s._transformID=-1,s._roundPixels=U.ROUND_PIXELS,s.batchUvs=null,s}return aa(r,e),Object.defineProperty(r.prototype,"geometry",{get:function(){return this._geometry},set:function(t){this._geometry!==t&&(this._geometry&&(this._geometry.refCount--,0===this._geometry.refCount&&this._geometry.dispose()),this._geometry=t,this._geometry&&this._geometry.refCount++,this.vertexDirty=-1)},enumerable:!1,configurable:!0}),Object.defineProperty(r.prototype,"uvBuffer",{get:function(){return this.geometry.buffers[1]},enumerable:!1,configurable:!0}),Object.defineProperty(r.prototype,"verticesBuffer",{get:function(){return this.geometry.buffers[0]},enumerable:!1,configurable:!0}),Object.defineProperty(r.prototype,"material",{get:function(){return this.shader},set:function(t){this.shader=t},enumerable:!1,configurable:!0}),Object.defineProperty(r.prototype,"blendMode",{get:function(){return this.state.blendMode},set:function(t){this.state.blendMode=t},enumerable:!1,configurable:!0}),Object.defineProperty(r.prototype,"roundPixels",{get:function(){return this._roundPixels},set:function(t){this._roundPixels!==t&&(this._transformID=-1),this._roundPixels=t},enumerable:!1,configurable:!0}),Object.defineProperty(r.prototype,"tint",{get:function(){return"tint"in this.shader?this.shader.tint:null},set:function(t){this.shader.tint=t},enumerable:!1,configurable:!0}),Object.defineProperty(r.prototype,"texture",{get:function(){return"texture"in this.shader?this.shader.texture:null},set:function(t){this.shader.texture=t},enumerable:!1,configurable:!0}),r.prototype._render=function(e){var i=this.geometry.buffers[0].data;this.shader.batchable&&this.drawMode===t.DRAW_MODES.TRIANGLES&&i.length<2*r.BATCHABLE_SIZE?this._renderToBatch(e):this._renderDefault(e)},r.prototype._renderDefault=function(t){var e=this.shader;e.alpha=this.worldAlpha,e.update&&e.update(),t.batch.flush(),e.uniforms.translationMatrix=this.transform.worldTransform.toArray(!0),t.shader.bind(e),t.state.set(this.state),t.geometry.bind(this.geometry,e),t.geometry.draw(this.drawMode,this.size,this.start,this.geometry.instanceCount)},r.prototype._renderToBatch=function(t){var e=this.geometry,r=this.shader;r.uvMatrix&&(r.uvMatrix.update(),this.calculateUvs()),this.calculateVertices(),this.indices=e.indexBuffer.data,this._tintRGB=r._tintRGB,this._texture=r.texture;var i=this.material.pluginName;t.batch.setObjectRenderer(t.plugins[i]),t.plugins[i].render(this)},r.prototype.calculateVertices=function(){var t=this.geometry.buffers[0],e=t.data,r=t._updateID;if(r!==this.vertexDirty||this._transformID!==this.transform._worldID){this._transformID=this.transform._worldID,this.vertexData.length!==e.length&&(this.vertexData=new Float32Array(e.length));for(var i=this.transform.worldTransform,n=i.a,o=i.b,s=i.c,a=i.d,h=i.tx,u=i.ty,l=this.vertexData,c=0;c>16)+(65280&t)+((255&t)<<16),this._colorDirty=!0)},enumerable:!1,configurable:!0}),e.prototype.update=function(){if(this._colorDirty){this._colorDirty=!1;var t=this.texture.baseTexture;se(this._tint,this._alpha,this.uniforms.uColor,t.alphaMode)}this.uvMatrix.update()&&(this.uniforms.uTextureMatrix=this.uvMatrix.mapCoord)},e}(Ci),fa=function(e){function r(r,i,n){var o=e.call(this)||this,s=new Ur(r),a=new Ur(i,!0),h=new Ur(n,!0,!0);return o.addAttribute("aVertexPosition",s,2,!1,t.TYPES.FLOAT).addAttribute("aTextureCoord",a,2,!1,t.TYPES.FLOAT).addIndex(h),o._updateId=-1,o}return aa(r,e),Object.defineProperty(r.prototype,"vertexDirtyId",{get:function(){return this.buffers[0]._updateID},enumerable:!1,configurable:!0}),r}(Yr),pa=function(t,e){return pa=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r])},pa(t,e)},_a=function(){this.info=[],this.common=[],this.page=[],this.char=[],this.kerning=[],this.distanceField=[]},va=function(){function t(){}return t.test=function(t){return"string"==typeof t&&0===t.indexOf("info face=")},t.parse=function(t){var e=t.match(/^[a-z]+\s+.+$/gm),r={info:[],common:[],page:[],char:[],chars:[],kerning:[],kernings:[],distanceField:[]};for(var i in e){var n=e[i].match(/^[a-z]+/gm)[0],o=e[i].match(/[a-zA-Z]+=([^\s"']+|"([^"]*)")/gm),s={};for(var a in o){var h=o[a].split("="),u=h[0],l=h[1].replace(/"/gm,""),c=parseFloat(l),d=isNaN(c)?l:c;s[u]=d}r[n].push(s)}var f=new _a;return r.info.forEach((function(t){return f.info.push({face:t.face,size:parseInt(t.size,10)})})),r.common.forEach((function(t){return f.common.push({lineHeight:parseInt(t.lineHeight,10)})})),r.page.forEach((function(t){return f.page.push({id:parseInt(t.id,10),file:t.file})})),r.char.forEach((function(t){return f.char.push({id:parseInt(t.id,10),page:parseInt(t.page,10),x:parseInt(t.x,10),y:parseInt(t.y,10),width:parseInt(t.width,10),height:parseInt(t.height,10),xoffset:parseInt(t.xoffset,10),yoffset:parseInt(t.yoffset,10),xadvance:parseInt(t.xadvance,10)})})),r.kerning.forEach((function(t){return f.kerning.push({first:parseInt(t.first,10),second:parseInt(t.second,10),amount:parseInt(t.amount,10)})})),r.distanceField.forEach((function(t){return f.distanceField.push({distanceRange:parseInt(t.distanceRange,10),fieldType:t.fieldType})})),f},t}(),ma=function(){function t(){}return t.test=function(t){return t instanceof XMLDocument&&t.getElementsByTagName("page").length&&null!==t.getElementsByTagName("info")[0].getAttribute("face")},t.parse=function(t){for(var e=new _a,r=t.getElementsByTagName("info"),i=t.getElementsByTagName("common"),n=t.getElementsByTagName("page"),o=t.getElementsByTagName("char"),s=t.getElementsByTagName("kerning"),a=t.getElementsByTagName("distanceField"),h=0;h")>-1){var e=(new globalThis.DOMParser).parseFromString(t,"text/xml");return ma.test(e)}return!1},t.parse=function(t){var e=(new globalThis.DOMParser).parseFromString(t,"text/xml");return ma.parse(e)},t}(),ga=[va,ma,ya];function Ta(t){for(var e=0;e=u-S*a){if(0===y)throw new Error("[BitmapFont] textureHeight "+u+"px is too small (fontFamily: '"+c.fontFamily+"', fontSize: "+c.fontSize+"px, char: '"+b+"')");--E,p=null,_=null,v=null,y=0,m=0,g=0}else if(g=Math.max(S+x.fontProperties.descent,g),R*a+m>=d){if(0===m)throw new Error("[BitmapFont] textureWidth "+h+"px is too small (fontFamily: '"+c.fontFamily+"', fontSize: "+c.fontSize+"px, char: '"+b+"')");--E,y+=g*a,y=Math.ceil(y),m=0,g=0}else{Ea(p,_,x,m,y,a,c);var O=xa(x.text);f.char.push({id:O,page:T.length-1,x:m/a,y:y/a,width:R,height:S,xoffset:0,yoffset:0,xadvance:Math.ceil(A-(c.dropShadow?c.dropShadowDistance:0)-(c.stroke?c.strokeThickness:0))}),m+=(R+2*s)*a,m=Math.ceil(m)}}if(!(null==i?void 0:i.skipKerning)){E=0;for(var M=l.length;E0&&o.x>l&&(fe(s,1+v-++y,1+E-v),E=v,v=-1,a.push(m),h.push(s.length>0?s[s.length-1].prevSpaces:0),p=Math.max(p,m),_++,o.x=0,o.y+=r.lineHeight,d=null,T=0)}}else a.push(f),h.push(-1),p=Math.max(p,f),++_,++y,o.x=0,o.y+=r.lineHeight,d=null,T=0}var S=u[u.length-1];"\r"!==S&&"\n"!==S&&(/(?:\s)/.test(S)&&(f=m),a.push(f),p=Math.max(p,f),h.push(-1));var R=[];for(E=0;E<=_;E++){var O=0;"right"===this._align?O=p-a[E]:"center"===this._align?O=(p-a[E])/2:"justify"===this._align&&(O=h[E]<0?0:(p-a[E])/h[E]),R.push(O)}var M=s.length,P={},I=[],D=this._activePagesMeshData;for(c.push.apply(c,D),E=0;E 0.99) {\r\n alpha = 1.0;\r\n }\r\n\r\n // NPM Textures, NPM outputs\r\n gl_FragColor = vec4(uColor.rgb, uColor.a * alpha);\r\n\r\n}\r\n"),uniforms:{uFWidth:0}}),F=t.BLEND_MODES.NORMAL_NPM);var L=new ca(C,N);L.blendMode=F,Q={index:0,indexCount:0,vertexCount:0,uvsCount:0,total:0,mesh:L,vertices:null,uvs:null,indices:null}}Q.index=0,Q.indexCount=0,Q.vertexCount=0,Q.uvsCount=0,Q.total=0;var B=this._textureCache;B[w]=B[w]||new Nr(Y.baseTexture),Q.mesh.texture=B[w],Q.mesh.tint=this._tint,I.push(Q),P[w]=Q}P[w].total++}for(E=0;E6*G)||Q.vertices.length<2*ca.BATCHABLE_SIZE)Q.vertices=new Float32Array(8*G),Q.uvs=new Float32Array(8*G),Q.indices=new Uint16Array(6*G);else for(var U=Q.total,k=Q.vertices,X=4*U*2;X=i&&(e=t-s-1),o+=a=a.replace("%value%",r[e].toString()),o+="\n"}return(n=n.replace("%blur%",o)).replace("%size%",t.toString())}(o);return(s=e.call(this,a,h)||this).horizontal=t,s.resolution=n,s._quality=0,s.quality=i,s.blur=r,s}return Ca(r,e),r.prototype.apply=function(e,r,i,n){if(i?this.horizontal?this.uniforms.strength=1/i.width*(i.width/r.width):this.uniforms.strength=1/i.height*(i.height/r.height):this.horizontal?this.uniforms.strength=1/e.renderer.width*(e.renderer.width/r.width):this.uniforms.strength=1/e.renderer.height*(e.renderer.height/r.height),this.uniforms.strength*=this.strength,this.uniforms.strength/=this.passes,1===this.passes)e.applyFilter(this,r,i,n);else{var o=e.getFilterTexture(),s=e.renderer,a=r,h=o;this.state.blend=!1,e.applyFilter(this,a,h,t.CLEAR_MODES.CLEAR);for(var u=1;u 0.0) {\n c.rgb /= c.a;\n }\n\n vec4 result;\n\n result.r = (m[0] * c.r);\n result.r += (m[1] * c.g);\n result.r += (m[2] * c.b);\n result.r += (m[3] * c.a);\n result.r += m[4];\n\n result.g = (m[5] * c.r);\n result.g += (m[6] * c.g);\n result.g += (m[7] * c.b);\n result.g += (m[8] * c.a);\n result.g += m[9];\n\n result.b = (m[10] * c.r);\n result.b += (m[11] * c.g);\n result.b += (m[12] * c.b);\n result.b += (m[13] * c.a);\n result.b += m[14];\n\n result.a = (m[15] * c.r);\n result.a += (m[16] * c.g);\n result.a += (m[17] * c.b);\n result.a += (m[18] * c.a);\n result.a += m[19];\n\n vec3 rgb = mix(c.rgb, result.rgb, uAlpha);\n\n // Premultiply alpha again.\n rgb *= result.a;\n\n gl_FragColor = vec4(rgb, result.a);\n}\n",r)||this).alpha=1,e}return function(t,e){function r(){this.constructor=t}Ga(t,e),t.prototype=null===e?Object.create(e):(r.prototype=e.prototype,new r)}(e,t),e.prototype._loadMatrix=function(t,e){void 0===e&&(e=!1);var r=t;e&&(this._multiply(r,this.uniforms.m,t),r=this._colorMatrix(r)),this.uniforms.m=r},e.prototype._multiply=function(t,e,r){return t[0]=e[0]*r[0]+e[1]*r[5]+e[2]*r[10]+e[3]*r[15],t[1]=e[0]*r[1]+e[1]*r[6]+e[2]*r[11]+e[3]*r[16],t[2]=e[0]*r[2]+e[1]*r[7]+e[2]*r[12]+e[3]*r[17],t[3]=e[0]*r[3]+e[1]*r[8]+e[2]*r[13]+e[3]*r[18],t[4]=e[0]*r[4]+e[1]*r[9]+e[2]*r[14]+e[3]*r[19]+e[4],t[5]=e[5]*r[0]+e[6]*r[5]+e[7]*r[10]+e[8]*r[15],t[6]=e[5]*r[1]+e[6]*r[6]+e[7]*r[11]+e[8]*r[16],t[7]=e[5]*r[2]+e[6]*r[7]+e[7]*r[12]+e[8]*r[17],t[8]=e[5]*r[3]+e[6]*r[8]+e[7]*r[13]+e[8]*r[18],t[9]=e[5]*r[4]+e[6]*r[9]+e[7]*r[14]+e[8]*r[19]+e[9],t[10]=e[10]*r[0]+e[11]*r[5]+e[12]*r[10]+e[13]*r[15],t[11]=e[10]*r[1]+e[11]*r[6]+e[12]*r[11]+e[13]*r[16],t[12]=e[10]*r[2]+e[11]*r[7]+e[12]*r[12]+e[13]*r[17],t[13]=e[10]*r[3]+e[11]*r[8]+e[12]*r[13]+e[13]*r[18],t[14]=e[10]*r[4]+e[11]*r[9]+e[12]*r[14]+e[13]*r[19]+e[14],t[15]=e[15]*r[0]+e[16]*r[5]+e[17]*r[10]+e[18]*r[15],t[16]=e[15]*r[1]+e[16]*r[6]+e[17]*r[11]+e[18]*r[16],t[17]=e[15]*r[2]+e[16]*r[7]+e[17]*r[12]+e[18]*r[17],t[18]=e[15]*r[3]+e[16]*r[8]+e[17]*r[13]+e[18]*r[18],t[19]=e[15]*r[4]+e[16]*r[9]+e[17]*r[14]+e[18]*r[19]+e[19],t},e.prototype._colorMatrix=function(t){var e=new Float32Array(t);return e[4]/=255,e[9]/=255,e[14]/=255,e[19]/=255,e},e.prototype.brightness=function(t,e){var r=[t,0,0,0,0,0,t,0,0,0,0,0,t,0,0,0,0,0,1,0];this._loadMatrix(r,e)},e.prototype.tint=function(t,e){var r=[(t>>16&255)/255,0,0,0,0,0,(t>>8&255)/255,0,0,0,0,0,(255&t)/255,0,0,0,0,0,1,0];this._loadMatrix(r,e)},e.prototype.greyscale=function(t,e){var r=[t,t,t,0,0,t,t,t,0,0,t,t,t,0,0,0,0,0,1,0];this._loadMatrix(r,e)},e.prototype.blackAndWhite=function(t){this._loadMatrix([.3,.6,.1,0,0,.3,.6,.1,0,0,.3,.6,.1,0,0,0,0,0,1,0],t)},e.prototype.hue=function(t,e){t=(t||0)/180*Math.PI;var r=Math.cos(t),i=Math.sin(t),n=1/3,o=(0,Math.sqrt)(n),s=[r+(1-r)*n,n*(1-r)-o*i,n*(1-r)+o*i,0,0,n*(1-r)+o*i,r+n*(1-r),n*(1-r)-o*i,0,0,n*(1-r)-o*i,n*(1-r)+o*i,r+n*(1-r),0,0,0,0,0,1,0];this._loadMatrix(s,e)},e.prototype.contrast=function(t,e){var r=(t||0)+1,i=-.5*(r-1),n=[r,0,0,0,i,0,r,0,0,i,0,0,r,0,i,0,0,0,1,0];this._loadMatrix(n,e)},e.prototype.saturate=function(t,e){void 0===t&&(t=0);var r=2*t/3+1,i=-.5*(r-1),n=[r,i,i,0,0,i,r,i,0,0,i,i,r,0,0,0,0,0,1,0];this._loadMatrix(n,e)},e.prototype.desaturate=function(){this.saturate(-1)},e.prototype.negative=function(t){this._loadMatrix([-1,0,0,1,0,0,-1,0,1,0,0,0,-1,1,0,0,0,0,1,0],t)},e.prototype.sepia=function(t){this._loadMatrix([.393,.7689999,.18899999,0,0,.349,.6859999,.16799999,0,0,.272,.5339999,.13099999,0,0,0,0,0,1,0],t)},e.prototype.technicolor=function(t){this._loadMatrix([1.9125277891456083,-.8545344976951645,-.09155508482755585,0,11.793603434377337,-.3087833385928097,1.7658908555458428,-.10601743074722245,0,-70.35205161461398,-.231103377548616,-.7501899197440212,1.847597816108189,0,30.950940869491138,0,0,0,1,0],t)},e.prototype.polaroid=function(t){this._loadMatrix([1.438,-.062,-.062,0,0,-.122,1.378,-.122,0,0,-.016,-.016,1.483,0,0,0,0,0,1,0],t)},e.prototype.toBGR=function(t){this._loadMatrix([0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0],t)},e.prototype.kodachrome=function(t){this._loadMatrix([1.1285582396593525,-.3967382283601348,-.03992559172921793,0,63.72958762196502,-.16404339962244616,1.0835251566291304,-.05498805115633132,0,24.732407896706203,-.16786010706155763,-.5603416277695248,1.6014850761964943,0,35.62982807460946,0,0,0,1,0],t)},e.prototype.browni=function(t){this._loadMatrix([.5997023498159715,.34553243048391263,-.2708298674538042,0,47.43192855600873,-.037703249837783157,.8609577587992641,.15059552388459913,0,-36.96841498319127,.24113635128153335,-.07441037908422492,.44972182064877153,0,-7.562075277591283,0,0,0,1,0],t)},e.prototype.vintage=function(t){this._loadMatrix([.6279345635605994,.3202183420819367,-.03965408211312453,0,9.651285835294123,.02578397704808868,.6441188644374771,.03259127616149294,0,7.462829176470591,.0466055556782719,-.0851232987247891,.5241648018700465,0,5.159190588235296,0,0,0,1,0],t)},e.prototype.colorTone=function(t,e,r,i,n){var o=((r=r||16770432)>>16&255)/255,s=(r>>8&255)/255,a=(255&r)/255,h=((i=i||3375104)>>16&255)/255,u=(i>>8&255)/255,l=(255&i)/255,c=[.3,.59,.11,0,0,o,s,a,t=t||.2,0,h,u,l,e=e||.15,0,o-h,s-u,a-l,0,0];this._loadMatrix(c,n)},e.prototype.night=function(t,e){var r=[-2*(t=t||.1),-t,0,0,0,-t,0,t,0,0,0,t,2*t,0,0,0,0,0,1,0];this._loadMatrix(r,e)},e.prototype.predator=function(t,e){var r=[11.224130630493164*t,-4.794486999511719*t,-2.8746118545532227*t,0*t,.40342438220977783*t,-3.6330697536468506*t,9.193157196044922*t,-2.951810836791992*t,0*t,-1.316135048866272*t,-3.2184197902679443*t,-4.2375030517578125*t,7.476448059082031*t,0*t,.8044459223747253*t,0,0,0,1,0];this._loadMatrix(r,e)},e.prototype.lsd=function(t){this._loadMatrix([2,-.4,.5,0,0,-.5,2,-.4,0,0,-.4,-.5,3,0,0,0,0,0,1,0],t)},e.prototype.reset=function(){this._loadMatrix([1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0],!1)},Object.defineProperty(e.prototype,"matrix",{get:function(){return this.uniforms.m},set:function(t){this.uniforms.m=t},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"alpha",{get:function(){return this.uniforms.uAlpha},set:function(t){this.uniforms.uAlpha=t},enumerable:!1,configurable:!0}),e}(Fi);Ua.prototype.grayscale=Ua.prototype.greyscale;var ka=function(t,e){return ka=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r])},ka(t,e)},Xa=function(t){function e(e,r){var i=this,n=new Ue;return e.renderable=!1,(i=t.call(this,"attribute vec2 aVertexPosition;\n\nuniform mat3 projectionMatrix;\nuniform mat3 filterMatrix;\n\nvarying vec2 vTextureCoord;\nvarying vec2 vFilterCoord;\n\nuniform vec4 inputSize;\nuniform vec4 outputFrame;\n\nvec4 filterVertexPosition( void )\n{\n vec2 position = aVertexPosition * max(outputFrame.zw, vec2(0.)) + outputFrame.xy;\n\n return vec4((projectionMatrix * vec3(position, 1.0)).xy, 0.0, 1.0);\n}\n\nvec2 filterTextureCoord( void )\n{\n return aVertexPosition * (outputFrame.zw * inputSize.zw);\n}\n\nvoid main(void)\n{\n\tgl_Position = filterVertexPosition();\n\tvTextureCoord = filterTextureCoord();\n\tvFilterCoord = ( filterMatrix * vec3( vTextureCoord, 1.0) ).xy;\n}\n","varying vec2 vFilterCoord;\nvarying vec2 vTextureCoord;\n\nuniform vec2 scale;\nuniform mat2 rotation;\nuniform sampler2D uSampler;\nuniform sampler2D mapSampler;\n\nuniform highp vec4 inputSize;\nuniform vec4 inputClamp;\n\nvoid main(void)\n{\n vec4 map = texture2D(mapSampler, vFilterCoord);\n\n map -= 0.5;\n map.xy = scale * inputSize.zw * (rotation * map.xy);\n\n gl_FragColor = texture2D(uSampler, clamp(vec2(vTextureCoord.x + map.x, vTextureCoord.y + map.y), inputClamp.xy, inputClamp.zw));\n}\n",{mapSampler:e._texture,filterMatrix:n,scale:{x:1,y:1},rotation:new Float32Array([1,0,0,1])})||this).maskSprite=e,i.maskMatrix=n,null==r&&(r=20),i.scale=new De(r,r),i}return function(t,e){function r(){this.constructor=t}ka(t,e),t.prototype=null===e?Object.create(e):(r.prototype=e.prototype,new r)}(e,t),e.prototype.apply=function(t,e,r,i){this.uniforms.filterMatrix=t.calculateSpriteMatrix(this.maskMatrix,this.maskSprite),this.uniforms.scale.x=this.scale.x,this.uniforms.scale.y=this.scale.y;var n=this.maskSprite.worldTransform,o=Math.sqrt(n.a*n.a+n.b*n.b),s=Math.sqrt(n.c*n.c+n.d*n.d);0!==o&&0!==s&&(this.uniforms.rotation[0]=n.a/o,this.uniforms.rotation[1]=n.b/o,this.uniforms.rotation[2]=n.c/s,this.uniforms.rotation[3]=n.d/s),t.applyFilter(this,e,r,i)},Object.defineProperty(e.prototype,"map",{get:function(){return this.uniforms.mapSampler},set:function(t){this.uniforms.mapSampler=t},enumerable:!1,configurable:!0}),e}(Fi),ja=function(t,e){return ja=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r])},ja(t,e)},Ha=function(t){function e(){return t.call(this,"\nattribute vec2 aVertexPosition;\n\nuniform mat3 projectionMatrix;\n\nvarying vec2 v_rgbNW;\nvarying vec2 v_rgbNE;\nvarying vec2 v_rgbSW;\nvarying vec2 v_rgbSE;\nvarying vec2 v_rgbM;\n\nvarying vec2 vFragCoord;\n\nuniform vec4 inputSize;\nuniform vec4 outputFrame;\n\nvec4 filterVertexPosition( void )\n{\n vec2 position = aVertexPosition * max(outputFrame.zw, vec2(0.)) + outputFrame.xy;\n\n return vec4((projectionMatrix * vec3(position, 1.0)).xy, 0.0, 1.0);\n}\n\nvoid texcoords(vec2 fragCoord, vec2 inverseVP,\n out vec2 v_rgbNW, out vec2 v_rgbNE,\n out vec2 v_rgbSW, out vec2 v_rgbSE,\n out vec2 v_rgbM) {\n v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP;\n v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP;\n v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP;\n v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP;\n v_rgbM = vec2(fragCoord * inverseVP);\n}\n\nvoid main(void) {\n\n gl_Position = filterVertexPosition();\n\n vFragCoord = aVertexPosition * outputFrame.zw;\n\n texcoords(vFragCoord, inputSize.zw, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM);\n}\n",'varying vec2 v_rgbNW;\nvarying vec2 v_rgbNE;\nvarying vec2 v_rgbSW;\nvarying vec2 v_rgbSE;\nvarying vec2 v_rgbM;\n\nvarying vec2 vFragCoord;\nuniform sampler2D uSampler;\nuniform highp vec4 inputSize;\n\n\n/**\n Basic FXAA implementation based on the code on geeks3d.com with the\n modification that the texture2DLod stuff was removed since it\'s\n unsupported by WebGL.\n\n --\n\n From:\n https://github.com/mitsuhiko/webgl-meincraft\n\n Copyright (c) 2011 by Armin Ronacher.\n\n Some rights reserved.\n\n Redistribution and use in source and binary forms, with or without\n modification, are permitted provided that the following conditions are\n met:\n\n * Redistributions of source code must retain the above copyright\n notice, this list of conditions and the following disclaimer.\n\n * Redistributions in binary form must reproduce the above\n copyright notice, this list of conditions and the following\n disclaimer in the documentation and/or other materials provided\n with the distribution.\n\n * The names of the contributors may not be used to endorse or\n promote products derived from this software without specific\n prior written permission.\n\n THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#ifndef FXAA_REDUCE_MIN\n#define FXAA_REDUCE_MIN (1.0/ 128.0)\n#endif\n#ifndef FXAA_REDUCE_MUL\n#define FXAA_REDUCE_MUL (1.0 / 8.0)\n#endif\n#ifndef FXAA_SPAN_MAX\n#define FXAA_SPAN_MAX 8.0\n#endif\n\n//optimized version for mobile, where dependent\n//texture reads can be a bottleneck\nvec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 inverseVP,\n vec2 v_rgbNW, vec2 v_rgbNE,\n vec2 v_rgbSW, vec2 v_rgbSE,\n vec2 v_rgbM) {\n vec4 color;\n vec3 rgbNW = texture2D(tex, v_rgbNW).xyz;\n vec3 rgbNE = texture2D(tex, v_rgbNE).xyz;\n vec3 rgbSW = texture2D(tex, v_rgbSW).xyz;\n vec3 rgbSE = texture2D(tex, v_rgbSE).xyz;\n vec4 texColor = texture2D(tex, v_rgbM);\n vec3 rgbM = texColor.xyz;\n vec3 luma = vec3(0.299, 0.587, 0.114);\n float lumaNW = dot(rgbNW, luma);\n float lumaNE = dot(rgbNE, luma);\n float lumaSW = dot(rgbSW, luma);\n float lumaSE = dot(rgbSE, luma);\n float lumaM = dot(rgbM, luma);\n float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));\n float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));\n\n mediump vec2 dir;\n dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));\n dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));\n\n float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) *\n (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);\n\n float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);\n dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),\n max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),\n dir * rcpDirMin)) * inverseVP;\n\n vec3 rgbA = 0.5 * (\n texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz +\n texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz);\n vec3 rgbB = rgbA * 0.5 + 0.25 * (\n texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz +\n texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz);\n\n float lumaB = dot(rgbB, luma);\n if ((lumaB < lumaMin) || (lumaB > lumaMax))\n color = vec4(rgbA, texColor.a);\n else\n color = vec4(rgbB, texColor.a);\n return color;\n}\n\nvoid main() {\n\n vec4 color;\n\n color = fxaa(uSampler, vFragCoord, inputSize.zw, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM);\n\n gl_FragColor = color;\n}\n')||this}return function(t,e){function r(){this.constructor=t}ja(t,e),t.prototype=null===e?Object.create(e):(r.prototype=e.prototype,new r)}(e,t),e}(Fi),Ya=function(t,e){return Ya=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r])},Ya(t,e)},Va=function(t){function e(e,r){void 0===e&&(e=.5),void 0===r&&(r=Math.random());var i=t.call(this,gn,"precision highp float;\n\nvarying vec2 vTextureCoord;\nvarying vec4 vColor;\n\nuniform float uNoise;\nuniform float uSeed;\nuniform sampler2D uSampler;\n\nfloat rand(vec2 co)\n{\n return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453);\n}\n\nvoid main()\n{\n vec4 color = texture2D(uSampler, vTextureCoord);\n float randomValue = rand(gl_FragCoord.xy * uSeed);\n float diff = (randomValue - 0.5) * uNoise;\n\n // Un-premultiply alpha before applying the color matrix. See issue #3539.\n if (color.a > 0.0) {\n color.rgb /= color.a;\n }\n\n color.r += diff;\n color.g += diff;\n color.b += diff;\n\n // Premultiply alpha again.\n color.rgb *= color.a;\n\n gl_FragColor = color;\n}\n",{uNoise:0,uSeed:0})||this;return i.noise=e,i.seed=r,i}return function(t,e){function r(){this.constructor=t}Ya(t,e),t.prototype=null===e?Object.create(e):(r.prototype=e.prototype,new r)}(e,t),Object.defineProperty(e.prototype,"noise",{get:function(){return this.uniforms.uNoise},set:function(t){this.uniforms.uNoise=t},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"seed",{get:function(){return this.uniforms.uSeed},set:function(t){this.uniforms.uSeed=t},enumerable:!1,configurable:!0}),e}(Fi),za=new Ue;Je.prototype._cacheAsBitmap=!1,Je.prototype._cacheData=null,Je.prototype._cacheAsBitmapResolution=null,Je.prototype._cacheAsBitmapMultisample=t.MSAA_QUALITY.NONE;var Wa=function(){this.textureCacheId=null,this.originalRender=null,this.originalRenderCanvas=null,this.originalCalculateBounds=null,this.originalGetLocalBounds=null,this.originalUpdateTransform=null,this.originalDestroy=null,this.originalMask=null,this.originalFilterArea=null,this.originalContainsPoint=null,this.sprite=null};Object.defineProperties(Je.prototype,{cacheAsBitmapResolution:{get:function(){return this._cacheAsBitmapResolution},set:function(t){t!==this._cacheAsBitmapResolution&&(this._cacheAsBitmapResolution=t,this.cacheAsBitmap&&(this.cacheAsBitmap=!1,this.cacheAsBitmap=!0))}},cacheAsBitmapMultisample:{get:function(){return this._cacheAsBitmapMultisample},set:function(t){t!==this._cacheAsBitmapMultisample&&(this._cacheAsBitmapMultisample=t,this.cacheAsBitmap&&(this.cacheAsBitmap=!1,this.cacheAsBitmap=!0))}},cacheAsBitmap:{get:function(){return this._cacheAsBitmap},set:function(t){var e;this._cacheAsBitmap!==t&&(this._cacheAsBitmap=t,t?(this._cacheData||(this._cacheData=new Wa),(e=this._cacheData).originalRender=this.render,e.originalRenderCanvas=this.renderCanvas,e.originalUpdateTransform=this.updateTransform,e.originalCalculateBounds=this.calculateBounds,e.originalGetLocalBounds=this.getLocalBounds,e.originalDestroy=this.destroy,e.originalContainsPoint=this.containsPoint,e.originalMask=this._mask,e.originalFilterArea=this.filterArea,this.render=this._renderCached,this.renderCanvas=this._renderCachedCanvas,this.destroy=this._cacheAsBitmapDestroy):((e=this._cacheData).sprite&&this._destroyCachedDisplayObject(),this.render=e.originalRender,this.renderCanvas=e.originalRenderCanvas,this.calculateBounds=e.originalCalculateBounds,this.getLocalBounds=e.originalGetLocalBounds,this.destroy=e.originalDestroy,this.updateTransform=e.originalUpdateTransform,this.containsPoint=e.originalContainsPoint,this._mask=e.originalMask,this.filterArea=e.originalFilterArea))}}}),Je.prototype._renderCached=function(t){!this.visible||this.worldAlpha<=0||!this.renderable||(this._initCachedDisplayObject(t),this._cacheData.sprite.transform._worldID=this.transform._worldID,this._cacheData.sprite.worldAlpha=this.worldAlpha,this._cacheData.sprite._render(t))},Je.prototype._initCachedDisplayObject=function(t){var e;if(!this._cacheData||!this._cacheData.sprite){var r=this.alpha;this.alpha=1,t.batch.flush();var i=this.getLocalBounds(null,!0).clone();if(this.filters&&this.filters.length){var n=this.filters[0].padding;i.pad(n)}i.ceil(U.RESOLUTION);var o=t.renderTexture.current,s=t.renderTexture.sourceFrame.clone(),a=t.renderTexture.destinationFrame.clone(),h=t.projection.transform,u=Fr.create({width:i.width,height:i.height,resolution:this.cacheAsBitmapResolution||t.resolution,multisample:null!==(e=this.cacheAsBitmapMultisample)&&void 0!==e?e:t.multisample}),l="cacheAsBitmap_"+ve();this._cacheData.textureCacheId=l,mr.addToCache(u.baseTexture,l),Nr.addToCache(u,l);var c=this.transform.localTransform.copyTo(za).invert().translate(-i.x,-i.y);this.render=this._cacheData.originalRender,t.render(this,{renderTexture:u,clear:!0,transform:c,skipUpdateTransform:!1}),t.framebuffer.blit(),t.projection.transform=h,t.renderTexture.bind(o,s,a),this.render=this._renderCached,this.updateTransform=this.displayObjectUpdateTransform,this.calculateBounds=this._calculateCachedBounds,this.getLocalBounds=this._getCachedLocalBounds,this._mask=null,this.filterArea=null,this.alpha=r;var d=new As(u);d.transform.worldTransform=this.transform.worldTransform,d.anchor.x=-i.x/i.width,d.anchor.y=-i.y/i.height,d.alpha=r,d._bounds=this._bounds,this._cacheData.sprite=d,this.transform._parentID=-1,this.parent?this.updateTransform():(this.enableTempParent(),this.updateTransform(),this.disableTempParent(null)),this.containsPoint=d.containsPoint.bind(d)}},Je.prototype._renderCachedCanvas=function(t){!this.visible||this.worldAlpha<=0||!this.renderable||(this._initCachedDisplayObjectCanvas(t),this._cacheData.sprite.worldAlpha=this.worldAlpha,this._cacheData.sprite._renderCanvas(t))},Je.prototype._initCachedDisplayObjectCanvas=function(t){if(!this._cacheData||!this._cacheData.sprite){var e=this.getLocalBounds(null,!0),r=this.alpha;this.alpha=1;var i=t.context,n=t._projTransform;e.ceil(U.RESOLUTION);var o=Fr.create({width:e.width,height:e.height}),s="cacheAsBitmap_"+ve();this._cacheData.textureCacheId=s,mr.addToCache(o.baseTexture,s),Nr.addToCache(o,s);var a=za;this.transform.localTransform.copyTo(a),a.invert(),a.tx-=e.x,a.ty-=e.y,this.renderCanvas=this._cacheData.originalRenderCanvas,t.render(this,{renderTexture:o,clear:!0,transform:a,skipUpdateTransform:!1}),t.context=i,t._projTransform=n,this.renderCanvas=this._renderCachedCanvas,this.updateTransform=this.displayObjectUpdateTransform,this.calculateBounds=this._calculateCachedBounds,this.getLocalBounds=this._getCachedLocalBounds,this._mask=null,this.filterArea=null,this.alpha=r;var h=new As(o);h.transform.worldTransform=this.transform.worldTransform,h.anchor.x=-e.x/e.width,h.anchor.y=-e.y/e.height,h.alpha=r,h._bounds=this._bounds,this._cacheData.sprite=h,this.transform._parentID=-1,this.parent?this.updateTransform():(this.parent=t._tempDisplayObjectParent,this.updateTransform(),this.parent=null),this.containsPoint=h.containsPoint.bind(h)}},Je.prototype._calculateCachedBounds=function(){this._bounds.clear(),this._cacheData.sprite.transform._worldID=this.transform._worldID,this._cacheData.sprite._calculateBounds(),this._bounds.updateID=this._boundsID},Je.prototype._getCachedLocalBounds=function(){return this._cacheData.sprite.getLocalBounds(null)},Je.prototype._destroyCachedDisplayObject=function(){this._cacheData.sprite._texture.destroy(!0),this._cacheData.sprite=null,mr.removeFromCache(this._cacheData.textureCacheId),Nr.removeFromCache(this._cacheData.textureCacheId),this._cacheData.textureCacheId=null},Je.prototype._cacheAsBitmapDestroy=function(t){this.cacheAsBitmap=!1,this.destroy(t)},Je.prototype.name=null,er.prototype.getChildByName=function(t,e){for(var r=0,i=this.children.length;r0){var d=a.x-t[l].x,f=a.y-t[l].y,p=Math.sqrt(d*d+f*f);a=t[l],s+=p/h}else s=l/(u-1);n[c]=s,n[c+1]=0,n[c+2]=s,n[c+3]=1}var _=0;for(l=0;l0?this.textureScale*this._width/2:this._width/2;i/=l,n/=l,i*=c,n*=c,o[u]=h.x+i,o[u+1]=h.y+n,o[u+2]=h.x-i,o[u+3]=h.y-n,r=h}this.buffers[0].update()}},e.prototype.update=function(){this.textureScale>0?this.build():this.updateVertices()},e}(fa),th=function(e){function r(r,i,n){void 0===n&&(n=0);var o=this,s=new $a(r.height,i,n),a=new da(r);return n>0&&(r.baseTexture.wrapMode=t.WRAP_MODES.REPEAT),(o=e.call(this,s,a)||this).autoUpdate=!0,o}return Qa(r,e),r.prototype._render=function(t){var r=this.geometry;(this.autoUpdate||r._width!==this.shader.texture.height)&&(r._width=this.shader.texture.height,r.update()),e.prototype._render.call(this,t)},r}(ca),eh=function(t){function e(e,r,i){var n=this,o=new Ja(e.width,e.height,r,i),s=new da(Nr.WHITE);return(n=t.call(this,o,s)||this).texture=e,n.autoResize=!0,n}return Qa(e,t),e.prototype.textureUpdated=function(){this._textureID=this.shader.texture._updateID;var t=this.geometry,e=this.shader.texture,r=e.width,i=e.height;!this.autoResize||t.width===r&&t.height===i||(t.width=this.shader.texture.width,t.height=this.shader.texture.height,t.build())},Object.defineProperty(e.prototype,"texture",{get:function(){return this.shader.texture},set:function(t){this.shader.texture!==t&&(this.shader.texture=t,this._textureID=-1,t.baseTexture.valid?this.textureUpdated():t.once("update",this.textureUpdated,this))},enumerable:!1,configurable:!0}),e.prototype._render=function(e){this._textureID!==this.shader.texture._updateID&&this.textureUpdated(),t.prototype._render.call(this,e)},e.prototype.destroy=function(e){this.shader.texture.off("update",this.textureUpdated,this),t.prototype.destroy.call(this,e)},e}(ca),rh=function(t){function e(e,r,i,n,o){void 0===e&&(e=Nr.EMPTY);var s=this,a=new fa(r,i,n);a.getBuffer("aVertexPosition").static=!1;var h=new da(e);return(s=t.call(this,a,h,null,o)||this).autoUpdate=!0,s}return Qa(e,t),Object.defineProperty(e.prototype,"vertices",{get:function(){return this.geometry.getBuffer("aVertexPosition").data},set:function(t){this.geometry.getBuffer("aVertexPosition").data=t},enumerable:!1,configurable:!0}),e.prototype._render=function(e){this.autoUpdate&&this.geometry.getBuffer("aVertexPosition").update(),t.prototype._render.call(this,e)},e}(ca),ih=function(t){function e(e,r,i,n,o){void 0===r&&(r=10),void 0===i&&(i=10),void 0===n&&(n=10),void 0===o&&(o=10);var s=t.call(this,Nr.WHITE,4,4)||this;return s._origWidth=e.orig.width,s._origHeight=e.orig.height,s._width=s._origWidth,s._height=s._origHeight,s._leftWidth=r,s._rightWidth=n,s._topHeight=i,s._bottomHeight=o,s.texture=e,s}return Qa(e,t),e.prototype.textureUpdated=function(){this._textureID=this.shader.texture._updateID,this._refresh()},Object.defineProperty(e.prototype,"vertices",{get:function(){return this.geometry.getBuffer("aVertexPosition").data},set:function(t){this.geometry.getBuffer("aVertexPosition").data=t},enumerable:!1,configurable:!0}),e.prototype.updateHorizontalVertices=function(){var t=this.vertices,e=this._getMinScale();t[9]=t[11]=t[13]=t[15]=this._topHeight*e,t[17]=t[19]=t[21]=t[23]=this._height-this._bottomHeight*e,t[25]=t[27]=t[29]=t[31]=this._height},e.prototype.updateVerticalVertices=function(){var t=this.vertices,e=this._getMinScale();t[2]=t[10]=t[18]=t[26]=this._leftWidth*e,t[4]=t[12]=t[20]=t[28]=this._width-this._rightWidth*e,t[6]=t[14]=t[22]=t[30]=this._width},e.prototype._getMinScale=function(){var t=this._leftWidth+this._rightWidth,e=this._width>t?1:this._width/t,r=this._topHeight+this._bottomHeight,i=this._height>r?1:this._height/r;return Math.min(e,i)},Object.defineProperty(e.prototype,"width",{get:function(){return this._width},set:function(t){this._width=t,this._refresh()},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"height",{get:function(){return this._height},set:function(t){this._height=t,this._refresh()},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"leftWidth",{get:function(){return this._leftWidth},set:function(t){this._leftWidth=t,this._refresh()},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"rightWidth",{get:function(){return this._rightWidth},set:function(t){this._rightWidth=t,this._refresh()},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"topHeight",{get:function(){return this._topHeight},set:function(t){this._topHeight=t,this._refresh()},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"bottomHeight",{get:function(){return this._bottomHeight},set:function(t){this._bottomHeight=t,this._refresh()},enumerable:!1,configurable:!0}),e.prototype._refresh=function(){var t=this.texture,e=this.geometry.buffers[1].data;this._origWidth=t.orig.width,this._origHeight=t.orig.height;var r=1/this._origWidth,i=1/this._origHeight;e[0]=e[8]=e[16]=e[24]=0,e[1]=e[3]=e[5]=e[7]=0,e[6]=e[14]=e[22]=e[30]=1,e[25]=e[27]=e[29]=e[31]=1,e[2]=e[10]=e[18]=e[26]=r*this._leftWidth,e[4]=e[12]=e[20]=e[28]=1-r*this._rightWidth,e[9]=e[11]=e[13]=e[15]=i*this._topHeight,e[17]=e[19]=e[21]=e[23]=1-i*this._bottomHeight,this.updateHorizontalVertices(),this.updateVerticalVertices(),this.geometry.buffers[0].update(),this.geometry.buffers[1].update()},e}(eh),nh=function(t,e){return nh=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r])},nh(t,e)},oh=function(e){function r(t,r){void 0===r&&(r=!0);var i=e.call(this,t[0]instanceof Nr?t[0]:t[0].texture)||this;return i._textures=null,i._durations=null,i._autoUpdate=r,i._isConnectedToTicker=!1,i.animationSpeed=1,i.loop=!0,i.updateAnchor=!1,i.onComplete=null,i.onFrameChange=null,i.onLoop=null,i._currentTime=0,i._playing=!1,i._previousFrame=null,i.textures=t,i}return function(t,e){function r(){this.constructor=t}nh(t,e),t.prototype=null===e?Object.create(e):(r.prototype=e.prototype,new r)}(r,e),r.prototype.stop=function(){this._playing&&(this._playing=!1,this._autoUpdate&&this._isConnectedToTicker&&(ar.shared.remove(this.update,this),this._isConnectedToTicker=!1))},r.prototype.play=function(){this._playing||(this._playing=!0,this._autoUpdate&&!this._isConnectedToTicker&&(ar.shared.add(this.update,this,t.UPDATE_PRIORITY.HIGH),this._isConnectedToTicker=!0))},r.prototype.gotoAndStop=function(t){this.stop();var e=this.currentFrame;this._currentTime=t,e!==this.currentFrame&&this.updateTexture()},r.prototype.gotoAndPlay=function(t){var e=this.currentFrame;this._currentTime=t,e!==this.currentFrame&&this.updateTexture(),this.play()},r.prototype.update=function(t){if(this._playing){var e=this.animationSpeed*t,r=this.currentFrame;if(null!==this._durations){var i=this._currentTime%1*this._durations[this.currentFrame];for(i+=e/60*1e3;i<0;)this._currentTime--,i+=this._durations[this.currentFrame];var n=Math.sign(this.animationSpeed*t);for(this._currentTime=Math.floor(this._currentTime);i>=this._durations[this.currentFrame];)i-=this._durations[this.currentFrame]*n,this._currentTime+=n;this._currentTime+=i/this._durations[this.currentFrame]}else this._currentTime+=e;this._currentTime<0&&!this.loop?(this.gotoAndStop(0),this.onComplete&&this.onComplete()):this._currentTime>=this._textures.length&&!this.loop?(this.gotoAndStop(this._textures.length-1),this.onComplete&&this.onComplete()):r!==this.currentFrame&&(this.loop&&this.onLoop&&(this.animationSpeed>0&&this.currentFramer)&&this.onLoop(),this.updateTexture())}},r.prototype.updateTexture=function(){var t=this.currentFrame;this._previousFrame!==t&&(this._previousFrame=t,this._texture=this._textures[t],this._textureID=-1,this._textureTrimmedID=-1,this._cachedTint=16777215,this.uvs=this._texture._uvs.uvsFloat32,this.updateAnchor&&this._anchor.copyFrom(this._texture.defaultAnchor),this.onFrameChange&&this.onFrameChange(this.currentFrame))},r.prototype.destroy=function(t){this.stop(),e.prototype.destroy.call(this,t),this.onComplete=null,this.onFrameChange=null,this.onLoop=null},r.fromFrames=function(t){for(var e=[],i=0;i { + const CHANNEL = "desktop-pet-model"; + const canvas = document.querySelector("#model"); + let application; + let model; + let modelId = ""; + let generation = 0; + let automatic = true; + let gazeEnabled = true; + let busy = false; + let expressionIndex = -1; + let expressionQueue = Promise.resolve(); + let mouthTarget = 0; + let mouthValue = 0; + let mouthAt = 0; + let pettingUntil = 0; + let nextMotionAt = 0; + let metadata = { expressions: [], motions: {} }; + + function notify(type, extra = {}) { parent.postMessage({ channel: CHANNEL, type, ...extra }, "*"); } + function fit() { + if (!application || !model) return; + const width = Math.max(1, innerWidth); + const height = Math.max(1, innerHeight); + application.renderer.resize(width, height); + const bounds = model.internalModel; + const scale = Math.min(width / bounds.width, height / bounds.height) * 0.94; + model.scale.set(scale); + model.anchor.set(0.5, 1); + model.position.set(width / 2, height - 2); + } + + function stopMotions() { + if (!model) return; + model.internalModel.motionManager.stopAllMotions(); + // Breathing and blinking remain active; large idle motions are explicitly paced below. + model.internalModel.motionManager.groups.idle = "__desktop_pet_no_automatic_motion__"; + } + + function expression(index) { + const target = model; + const token = generation; + expressionIndex = index; + expressionQueue = expressionQueue.then(async () => { + if (!target || model !== target || generation !== token) return; + const manager = target.internalModel.motionManager.expressionManager; + if (index < 0 && manager) { + // The library restores currentExpression after motions; neutral must persist too. + manager.currentExpression = manager.defaultExpression; + manager.resetExpression(); + } else if (manager && !(await manager.setExpression(index))) { notify("action-error"); return; } + if (model === target) notify("expression", { index }); + }).catch(() => notify("action-error")); + } + + function motion(group, index = 0) { + if (!automatic || !model || !Object.hasOwn(metadata.motions, group)) return; + if (!Number.isInteger(index) || index < 0 || index >= metadata.motions[group]) return; + const target = model; + target.motion(group, index, 3).then((started) => { if (target === model) notify(started ? "motion" : "action-error", { group, index }); }) + .catch(() => notify("action-error")); + nextMotionAt = performance.now() + 45000; + } + + async function load(data) { + const token = ++generation; + modelId = data.id; + automatic = data.automatic !== false; + gazeEnabled = data.gaze !== false; + busy = data.busy === true; + expressionIndex = -1; + mouthTarget = mouthValue = 0; + model?.destroy({ children: true, texture: true, baseTexture: true }); + model = null; + try { + if (!window.Live2DCubismCore || !window.PIXI?.live2d) throw new Error(); + if (!application) { + application = new PIXI.Application({ view: canvas, backgroundAlpha: 0, antialias: true, + autoDensity: true, resolution: Math.min(devicePixelRatio || 1, 2), preserveDrawingBuffer: true }); + application.ticker.maxFPS = 30; + } + const url = `/models/${modelId}/model.model3.json`; + const descriptor = await (await fetch(url)).json(); + const refs = descriptor.FileReferences; + metadata = { expressions: (refs.Expressions || []).map((entry) => entry.Name), + motions: Object.fromEntries(Object.entries(refs.Motions || {}).map(([group, entries]) => [group, entries.length])) }; + const loaded = await PIXI.live2d.Live2DModel.from(url, { autoInteract: false, idleMotionGroup: "__desktop_pet_no_automatic_motion__" }); + if (generation !== token) { loaded.destroy({ children: true, texture: true, baseTexture: true }); return; } + model = loaded; + application.stage.addChild(model); + stopMotions(); + fit(); + nextMotionAt = performance.now() + 35000; + const internal = model.internalModel; + const core = internal.coreModel; + const ids = new Set(core.getModel().parameters.ids); + const lips = descriptor.Groups?.find((group) => group.Name === "LipSync")?.Ids || ["ParamMouthOpenY"]; + internal.on("beforeModelUpdate", () => { + const now = performance.now(); + if (now - mouthAt > 300) mouthTarget = 0; + mouthValue += (mouthTarget - mouthValue) * 0.4; + if (mouthTarget > 0 || mouthValue > 0.005) { + for (const id of lips) if (ids.has(id)) core.setParameterValueById(id, mouthValue); + } + if (automatic && now < pettingUntil) { + const weight = Math.min(1, (pettingUntil - now) / 400); + if (ids.has("ParamAngleZ")) core.addParameterValueById("ParamAngleZ", -4 * weight); + } + if (automatic && !busy && now > nextMotionAt) { + const group = Object.keys(metadata.motions).find((key) => /^idle$/i.test(key)); + nextMotionAt = now + 45000 + Math.random() * 15000; + if (group && metadata.motions[group]) model.motion(group, 0, 1).catch(() => {}); + } + }); + notify("loaded", { expressions: metadata.expressions, motions: metadata.motions }); + } catch { + if (generation === token) notify("error"); + } + } + + window.addEventListener("message", (event) => { + const data = event.data; + if (event.source !== parent || event.origin !== "null" || !data || data.channel !== CHANNEL) return; + if (data.type === "load" && /^imported-[a-f0-9]{24}$/.test(data.id)) { load(data); return; } + if (!model || data.id !== modelId) return; + if (data.type === "options") { + const changed = automatic !== (data.automatic !== false); + automatic = data.automatic !== false; + gazeEnabled = data.gaze !== false; + if (data.busy === true && !busy) stopMotions(); + busy = data.busy === true; + if (changed) { stopMotions(); nextMotionAt = performance.now() + 45000; } + if (!gazeEnabled || !automatic) model.internalModel.focusController.focus(0, 0); + } else if (data.type === "gaze") { + if (!automatic || !gazeEnabled || !Number.isFinite(data.x) || !Number.isFinite(data.y)) return; + model.internalModel.focusController.focus(Math.max(-0.35, Math.min(0.35, data.x)), Math.max(-0.25, Math.min(0.25, data.y))); + } else if (data.type === "mouth" && Number.isFinite(data.value)) { + mouthTarget = Math.max(0, Math.min(1, data.value)); mouthAt = performance.now(); + } else if (data.type === "cycle") { + expression((expressionIndex + 2) % (metadata.expressions.length + 1) - 1); + } else if (data.type === "expression" && Number.isInteger(data.index) && data.index >= -1 && data.index < metadata.expressions.length) { + expression(data.index); + } else if (data.type === "motion") { + motion(data.group, data.index); + } else if (data.type === "touch" && automatic && !busy) { + pettingUntil = performance.now() + 1200; + const group = Object.keys(metadata.motions).find((key) => /tapbody|tap_body|touch/i.test(key)); + if (group && metadata.motions[group]) motion(group, 0); + } + }); + window.addEventListener("resize", fit); + document.addEventListener("visibilitychange", () => { + if (document.hidden) application?.ticker.stop(); + else application?.ticker.start(); + }); + notify("boot"); +})(); diff --git a/src/main.js b/src/main.js index 6053b22..7ab9271 100644 --- a/src/main.js +++ b/src/main.js @@ -8,17 +8,25 @@ const { Notification, safeStorage, dialog, + protocol, + session, + shell, } = require("electron"); const fs = require("node:fs"); const path = require("node:path"); const i18n = require("./i18n"); const validation = require("./config-validation"); const { readChatResponse } = require("./chat-response"); +const { AUDIO_LIMIT, ERROR_LIMIT, readResponseBytes, readResponseJson, returnedAudioUrl, audioDataUrl: validateAudioDataUrl, redactServiceText } = require("./network-safety"); const { expressionInstruction, parseCompanionReply } = require("./companion-response"); const { companionBounds } = require("./companion-layout"); const { modelsEndpoint, readModelList } = require("./model-list"); const { readPack, installPack } = require("./character-import"); const { pathToFileURL } = require("node:url"); +const { readLive2DPack, installLive2DPack } = require("./live2d-import"); +const live2dHost = require("./live2d-host"); + +protocol?.registerSchemesAsPrivileged([{ scheme: "pet-live2d", privileges: { standard: true, secure: true, supportFetchAPI: true, corsEnabled: true } }]); const BASE_SIZE = { width: 192, height: 208 }; const BUBBLE_HEIGHT = 132; @@ -121,28 +129,54 @@ function importedCharactersDir() { return path.join(app.getPath("userData"), "ch async function previewCharacterImport(event, kind) { const owner = BrowserWindow.fromWebContents(event.sender); + const live2d = kind === "live2d"; const result = await dialog.showOpenDialog(owner, kind === "folder" ? { properties: ["openDirectory"] } - : { properties: ["openFile"], filters: [{ name: "ZIP", extensions: ["zip"] }] }); + : { properties: ["openFile"], filters: [{ name: live2d ? "Live2D" : "ZIP", extensions: live2d ? ["json", "zip"] : ["zip"] }] }); if (result.canceled || !result.filePaths.length) return { cancelled: true }; try { - const pack = readPack(result.filePaths[0], (bytes) => !nativeImage.createFromBuffer(bytes).isEmpty()); + const pack = (live2d ? readLive2DPack : readPack)(result.filePaths[0], (bytes) => !nativeImage.createFromBuffer(bytes).isEmpty()); const token = require("node:crypto").randomUUID(); pendingImport = { pack, token, sender: event.sender.id, expires: Date.now() + 600000 }; - return { token, name: pack.manifest.name, description: pack.manifest.description, - preview: `data:image/png;base64,${pack.files[pack.manifest.preview].toString("base64")}` }; + return { token, name: pack.manifest.name, description: pack.manifest.description, type: pack.manifest.type || "sprite", + preview: live2d ? "" : `data:image/png;base64,${pack.files[pack.manifest.preview].toString("base64")}` }; } catch { return { error: "invalid_pack" }; } } function confirmCharacterImport(event, token) { if (!pendingImport || pendingImport.token !== token || pendingImport.sender !== event.sender.id || pendingImport.expires < Date.now()) return { error: "expired" }; try { - installPack(pendingImport.pack, importedCharactersDir()); + (pendingImport.pack.manifest.type === "live2d" ? installLive2DPack : installPack)(pendingImport.pack, importedCharactersDir()); pendingImport = null; return { ok: true, ...chatState() }; } catch { return { error: "import_failed" }; } } +async function importLive2DRuntime(event) { + const result = await dialog.showOpenDialog(BrowserWindow.fromWebContents(event.sender), { + properties: ["openFile"], filters: [{ name: "Cubism Core", extensions: ["js"] }], + }); + if (result.canceled || !result.filePaths.length) return { cancelled: true }; + try { + live2dHost.installCore(result.filePaths[0], app.getPath("userData")); + mainWindow?.webContents.send("app-state-updated", appState()); + return { ok: true }; + } catch { return { error: "invalid_runtime" }; } +} + +function performModelAction(_event, action) { + const pack = getCharacterPack(); + if (pack?.type !== "live2d" || !mainWindow || !action) return false; + if (action.type === "motion" && settings.expressionMode === "clickOnly") return false; + const valid = action.type === "expression" + ? Number.isInteger(action.index) && action.index >= -1 && action.index < pack.expressions.length + : action.type === "motion" && Object.hasOwn(pack.motions, action.group) + && Number.isInteger(action.index) && action.index >= 0 && action.index < pack.motions[action.group]; + if (!valid) return false; + mainWindow.webContents.send("model-action", { type: action.type, index: action.index, group: action.group, id: pack.id }); + return true; +} + async function removeCharacterImport(event, id) { if (!/^imported-[a-f0-9]{24}$/.test(id)) return { error: "invalid_id" }; const result = await dialog.showMessageBox(BrowserWindow.fromWebContents(event.sender), { @@ -293,6 +327,16 @@ function listCharacterPacks() { try { const root = path.join(importedCharactersDir(), id); const raw = JSON.parse(fs.readFileSync(path.join(root, "character.json"), "utf8")); + if (raw.type === "live2d") { + if (raw.model !== "model.model3.json" || !Array.isArray(raw.resources)) return null; + return { id, type: "live2d", name: String(raw.name || "Character").slice(0, 80), description: "", imported: true, + frame: { width: 768, height: 832 }, columns: 1, + states: Object.fromEntries(["idle", "happy", "shy", "review", "failed", "waving"].map((key) => [key, { row: 0, frames: 1, interval: 1000 }])), + automaticActions: [], clickActions: [], staticExpressions: [], + expressions: Array.isArray(raw.expressions) ? raw.expressions.slice(0, 64).map((name) => String(name).slice(0, 80)) : [], + motions: raw.motions && typeof raw.motions === "object" ? raw.motions : {}, + }; + } const pack = normalizeCharacterPack(raw, id); return { ...pack, id, imported: true, absoluteSpritePath: path.join(root, raw.sprite), spritePath: pathToFileURL(path.join(root, raw.sprite)).href, @@ -563,6 +607,11 @@ function normalizePersonaSettings(rawPersona = {}) { speakingStyle: normalizeLongText(raw.speakingStyle, 1200), background: normalizeLongText(raw.background, 1600), extraRules: normalizeLongText(raw.extraRules, 1600), + live2dGaze: raw.live2dGaze !== false, + live2dExpressions: Object.fromEntries(["happy", "shy", "review", "failed"].map((key) => { + const value = raw.live2dExpressions?.[key]; + return [key, Number.isInteger(value) && value >= 0 && value < 64 ? value : -1]; + })), }; } @@ -699,10 +748,11 @@ function createWindow() { preload: path.join(__dirname, "preload.js"), contextIsolation: true, nodeIntegration: false, - sandbox: false, + sandbox: true, }, }); + protectWindow(mainWindow, "index.html"); mainWindow.setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true }); mainWindow.loadFile(path.join(__dirname, "index.html")); mainWindow.once("ready-to-show", () => mainWindow.showInactive()); @@ -712,6 +762,18 @@ function createWindow() { mainWindow.webContents.on("did-start-loading", () => stopVoice()); } +function protectWindow(window, page) { + const localUrl = pathToFileURL(path.join(__dirname, page)).href; + window.webContents.setWindowOpenHandler(() => ({ action: "deny" })); + window.webContents.on("will-navigate", (event, url) => { if (url !== localUrl) event.preventDefault(); }); + window.webContents.on("will-frame-navigate", (event) => { + const allowed = event.isMainFrame ? event.url === localUrl + : page === "index.html" && event.url === `${live2dHost.ORIGIN}/index.html`; + if (!allowed) event.preventDefault(); + }); + window.webContents.on("will-attach-webview", (event) => event.preventDefault()); +} + function enableInputMenu(window) { window.webContents.on("context-menu", (_event, params) => { if (!params.isEditable) return; @@ -752,10 +814,11 @@ function createChatWindow() { preload: path.join(__dirname, "preload.js"), contextIsolation: true, nodeIntegration: false, - sandbox: false, + sandbox: true, }, }); + protectWindow(chatWindow, "chat.html"); chatWindow.loadFile(path.join(__dirname, "chat.html")); enableInputMenu(chatWindow); chatWindow.once("ready-to-show", () => chatWindow.show()); @@ -786,10 +849,11 @@ function createQuickChatWindow() { preload: path.join(__dirname, "preload.js"), contextIsolation: true, nodeIntegration: false, - sandbox: false, + sandbox: true, }, }); + protectWindow(quickChatWindow, "quick-chat.html"); quickChatWindow.loadFile(path.join(__dirname, "quick-chat.html")); enableInputMenu(quickChatWindow); quickChatWindow.once("ready-to-show", () => quickChatWindow.show()); @@ -817,10 +881,11 @@ function createCompanionSettingsWindow() { preload: path.join(__dirname, "preload.js"), contextIsolation: true, nodeIntegration: false, - sandbox: false, + sandbox: true, }, }); + protectWindow(companionSettingsWindow, "settings.html"); companionSettingsWindow.loadFile(path.join(__dirname, "settings.html")); enableInputMenu(companionSettingsWindow); companionSettingsWindow.once("ready-to-show", () => companionSettingsWindow.show()); @@ -1125,6 +1190,9 @@ function chatState() { automaticActionCount: pack.automaticActions.length, clickActionCount: pack.clickActions.length, imported: pack.imported === true, + type: pack.type || "sprite", + expressions: pack.expressions || [], + motions: pack.motions || {}, })); return { language: settings.language, @@ -1277,6 +1345,7 @@ async function requestAssistantReply(userText, controller = new AbortController( } const response = await fetch(llmEndpoint(assistant.baseUrl), { method: "POST", + redirect: "error", headers, signal: controller.signal, body: JSON.stringify({ @@ -1288,7 +1357,7 @@ async function requestAssistantReply(userText, controller = new AbortController( }); if (!response.ok) { - const detail = await responseErrorText(response); + const detail = await responseErrorText(response, [assistant.apiKey]); return { reply: t("assistant.statusError", { status: response.status, @@ -1346,6 +1415,7 @@ async function testAssistantConnection(_event, patch = {}) { if (assistant.apiKey) headers.Authorization = `Bearer ${assistant.apiKey}`; const response = await fetch(llmEndpoint(assistant.baseUrl), { method: "POST", + redirect: "error", headers, signal: controller.signal, body: JSON.stringify({ @@ -1359,7 +1429,7 @@ async function testAssistantConnection(_event, patch = {}) { }), }); if (!response.ok) { - const detail = await responseErrorText(response); + const detail = await responseErrorText(response, [assistant.apiKey]); return { ok: false, message: t("assistant.test.statusError", { @@ -1550,46 +1620,50 @@ function appendQuery(url, params) { function audioContentType(response, provider, tts = settings.tts || DEFAULT_SETTINGS.tts) { const contentType = response.headers.get("content-type"); - if (contentType && contentType.includes("audio/")) return contentType.split(";")[0]; + if (/^audio\/(wav|x-wav|wave|mpeg|mp3|mp4|ogg|aac|flac|webm)(;|$)/i.test(contentType || "")) return contentType.split(";")[0]; if (provider === "gptsovits") return `audio/${tts.mediaType || "wav"}`; - return contentType || "audio/mpeg"; + return "audio/mpeg"; } async function audioDataFromResponse(response, provider, tts = settings.tts || DEFAULT_SETTINGS.tts, signal) { const contentType = response.headers.get("content-type") || ""; if (contentType.includes("application/json")) { - const data = await response.json(); + const data = await readResponseJson(response, Math.ceil(AUDIO_LIMIT / 3) * 4 + 65536); const audioValue = data.audioDataUrl || data.audio_url || data.url || data.audio || data.audio_base64; if (!audioValue) return null; if (typeof audioValue === "string" && audioValue.startsWith("data:")) { - return audioValue; + return validateAudioDataUrl(audioValue); } if (typeof audioValue === "string" && /^https?:\/\//.test(audioValue)) { - const audioResponse = await fetch(audioValue, { signal }); + const target = returnedAudioUrl(audioValue, ttsEndpoint(tts)); + const audioResponse = await fetch(target, { signal, redirect: "error" }); if (!audioResponse.ok) return null; - const audioBuffer = Buffer.from(await audioResponse.arrayBuffer()); + const audioBuffer = await readResponseBytes(audioResponse, AUDIO_LIMIT); + if (!audioBuffer.length) return null; return `data:${audioContentType(audioResponse, provider, tts)};base64,${audioBuffer.toString("base64")}`; } if (typeof audioValue === "string") { const mediaType = provider === "gptsovits" ? tts.mediaType : "mpeg"; - return `data:audio/${mediaType || "mpeg"};base64,${audioValue}`; + return validateAudioDataUrl(`data:audio/${mediaType || "mpeg"};base64,${audioValue}`); } return null; } - const buffer = Buffer.from(await response.arrayBuffer()); + const buffer = await readResponseBytes(response, AUDIO_LIMIT); if (!buffer.length) return null; return `data:${audioContentType(response, provider, tts)};base64,${buffer.toString("base64")}`; } -async function responseErrorText(response) { +async function responseErrorText(response, secrets = []) { try { + const body = (await readResponseBytes(response, ERROR_LIMIT)).toString("utf8"); const contentType = response.headers.get("content-type") || ""; + const sensitive = [...secrets, settings.assistant?.apiKey, settings.tts?.apiKey]; if (contentType.includes("application/json")) { - const data = await response.json(); + const data = JSON.parse(body); const message = data.message || data.error?.message || data.error || data.Exception || JSON.stringify(data); - return String(message).replace(/\s+/g, " ").slice(0, 160); + return redactServiceText(message, sensitive).replace(/\s+/g, " ").slice(0, 160); } - return (await response.text()).replace(/\s+/g, " ").slice(0, 160); + return redactServiceText(body, sensitive).replace(/\s+/g, " ").slice(0, 160); } catch { return ""; } @@ -1641,9 +1715,9 @@ async function synthesizeSpeechWithSettings(rawText, nextSettings = settings, co } } - const response = await fetch(url, requestOptions); + const response = await fetch(url, { ...requestOptions, redirect: "error" }); if (!response.ok) { - const detail = await responseErrorText(response); + const detail = await responseErrorText(response, [tts.apiKey]); return { ok: false, error: detail ? `tts_status_${response.status}: ${detail}` : `tts_status_${response.status}` }; } const audioDataUrl = await audioDataFromResponse(response, tts.provider, tts, controller.signal); @@ -1651,6 +1725,8 @@ async function synthesizeSpeechWithSettings(rawText, nextSettings = settings, co return { ok: true, audioDataUrl }; } catch (error) { if (controller.signal.aborted && !expired) return { ok: false, cancelled: true }; + if (error?.message === "audio_origin_not_allowed") return { ok: false, error: t("tts.audioOrigin", {}, nextSettings) }; + if (error?.message === "response_too_large") return { ok: false, error: t("tts.responseTooLarge", {}, nextSettings) }; return { ok: false, error: error?.name === "AbortError" ? "tts_timeout" : "tts_request_failed" }; } finally { clearTimeout(timeout); @@ -1907,41 +1983,58 @@ function setApplicationMenu() { app.whenReady().then(() => { app.setName(t("app.name")); + protocol.handle("pet-live2d", live2dHost.createModelHandler({ userData: app.getPath("userData"), sourceDir: __dirname, getActiveCharacter: getCharacterPack })); + session.defaultSession.setPermissionRequestHandler((_contents, _permission, callback) => callback(false)); + session.defaultSession.setPermissionCheckHandler(() => false); createWindow(); - ipcMain.handle("get-app-state", () => appState()); - ipcMain.handle("get-chat-state", () => chatState()); - ipcMain.handle("save-chat-config", (_event, patch) => applyChatConfigPatch(patch)); - ipcMain.handle("test-assistant-connection", testAssistantConnection); - ipcMain.handle("list-assistant-models", listAssistantModels); - ipcMain.handle("test-tts-connection", testTtsConnection); - ipcMain.handle("send-chat-message", sendChatMessage); - ipcMain.handle("clear-chat-history", clearChatHistory); - ipcMain.handle("stop-chat", stopChat); - ipcMain.handle("confirm-discard", confirmDiscard); - ipcMain.handle("preview-character-import", previewCharacterImport); - ipcMain.handle("confirm-character-import", confirmCharacterImport); - ipcMain.handle("remove-character-import", removeCharacterImport); - ipcMain.handle("begin-speech", beginSpeech); - ipcMain.on("speech-state-changed", speechStateChanged); - ipcMain.handle("stop-voice", stopVoice); - ipcMain.handle("replay-speech", replaySpeech); - ipcMain.handle("synthesize-speech", synthesizeSpeech); - ipcMain.on("set-settings", (_event, patch) => updateSettings(patch)); - ipcMain.on("record-interaction", (_event, kind) => updateMoodFromInteraction(kind)); - ipcMain.on("present-notification", (event, notice) => { + // Only our top-level local windows may invoke the preload bridge. + const trusted = (event) => [mainWindow, chatWindow, quickChatWindow, companionSettingsWindow].some((window) => + window && !window.isDestroyed() && event.sender === window.webContents && event.senderFrame === window.webContents.mainFrame + && ["index.html", "chat.html", "quick-chat.html", "settings.html"].some((page) => event.senderFrame.url === pathToFileURL(path.join(__dirname, page)).href)); + const handle = (channel, callback) => ipcMain.handle(channel, (event, ...args) => { + if (!trusted(event)) throw new Error("Unauthorized window"); + return callback(event, ...args); + }); + const on = (channel, callback) => ipcMain.on(channel, (event, ...args) => { if (trusted(event)) callback(event, ...args); }); + handle("get-live2d-runtime", () => ({ ready: live2dHost.runtimeReady(app.getPath("userData")) })); + handle("import-live2d-runtime", importLive2DRuntime); + handle("perform-model-action", performModelAction); + on("open-live2d-download", () => { shell.openExternal(live2dHost.CORE_URL).catch(() => {}); }); + + handle("get-app-state", () => appState()); + handle("get-chat-state", () => chatState()); + handle("save-chat-config", (_event, patch) => applyChatConfigPatch(patch)); + handle("test-assistant-connection", testAssistantConnection); + handle("list-assistant-models", listAssistantModels); + handle("test-tts-connection", testTtsConnection); + handle("send-chat-message", sendChatMessage); + handle("clear-chat-history", clearChatHistory); + handle("stop-chat", stopChat); + handle("confirm-discard", confirmDiscard); + handle("preview-character-import", previewCharacterImport); + handle("confirm-character-import", confirmCharacterImport); + handle("remove-character-import", removeCharacterImport); + handle("begin-speech", beginSpeech); + on("speech-state-changed", speechStateChanged); + handle("stop-voice", stopVoice); + handle("replay-speech", replaySpeech); + handle("synthesize-speech", synthesizeSpeech); + on("set-settings", (_event, patch) => updateSettings(patch)); + on("record-interaction", (_event, kind) => updateMoodFromInteraction(kind)); + on("present-notification", (event, notice) => { if (event.sender !== mainWindow?.webContents || !Notification.isSupported()) return; const title = normalizeCompactText(notice?.title, 120); const body = normalizeLongText(notice?.body, 600); if (title || body) new Notification({ title, body, silent: true }).show(); }); - ipcMain.on("open-chat-window", createChatWindow); - ipcMain.on("open-quick-chat-window", createQuickChatWindow); - ipcMain.on("open-companion-settings", createCompanionSettingsWindow); - ipcMain.on("show-context-menu", showContextMenu); - ipcMain.on("drag-start", beginDrag); - ipcMain.handle("drag-move", moveDrag); - ipcMain.on("drag-end", endDrag); + on("open-chat-window", createChatWindow); + on("open-quick-chat-window", createQuickChatWindow); + on("open-companion-settings", createCompanionSettingsWindow); + on("show-context-menu", showContextMenu); + on("drag-start", beginDrag); + handle("drag-move", moveDrag); + on("drag-end", endDrag); if (process.platform === "darwin") { app.dock.hide(); diff --git a/src/network-safety.js b/src/network-safety.js new file mode 100644 index 0000000..8e41252 --- /dev/null +++ b/src/network-safety.js @@ -0,0 +1,61 @@ +const CHAT_LIMIT = 2 * 1024 * 1024; +const AUDIO_LIMIT = 24 * 1024 * 1024; +const ERROR_LIMIT = 32 * 1024; + +async function readResponseBytes(response, limit) { + const declared = Number(response.headers.get("content-length")); + if (Number.isFinite(declared) && declared > limit) { + await response.body?.cancel().catch(() => {}); + throw new Error("response_too_large"); + } + if (!response.body) return Buffer.alloc(0); + const reader = response.body.getReader(); + const chunks = []; + let size = 0; + try { + for (;;) { + const { done, value } = await reader.read(); + if (done) break; + size += value.byteLength; + if (size > limit) throw new Error("response_too_large"); + chunks.push(Buffer.from(value)); + } + return Buffer.concat(chunks, size); + } finally { + await reader.cancel().catch(() => {}); + reader.releaseLock(); + } +} + +async function readResponseJson(response, limit = CHAT_LIMIT) { + return JSON.parse((await readResponseBytes(response, limit)).toString("utf8")); +} + +function returnedAudioUrl(value, endpoint) { + const target = new URL(value); + const service = new URL(endpoint); + // Only the endpoint chosen by the user has network authority, not a URL in its reply. + if (!["http:", "https:"].includes(target.protocol) || target.origin !== service.origin + || target.username || target.password) throw new Error("audio_origin_not_allowed"); + target.hash = ""; + return target.href; +} + +function audioDataUrl(value) { + const match = /^data:(audio\/(?:wav|x-wav|wave|mpeg|mp3|mp4|ogg|aac|flac|webm));base64,([A-Za-z0-9+/]*={0,2})$/i.exec(value); + if (!match || !match[2] || match[2].length > Math.ceil(AUDIO_LIMIT / 3) * 4) throw new Error("invalid_audio"); + return `data:${match[1].toLowerCase()};base64,${match[2]}`; +} + +function redactServiceText(value, secrets = []) { + let text = String(value || ""); + for (const secret of secrets.filter((item) => typeof item === "string" && item.length)) { + for (const form of new Set([secret, encodeURIComponent(secret)])) text = text.split(form).join("[redacted]"); + } + return text.replace(/\bsk-[A-Za-z0-9_-]{12,}\b/g, "[redacted]") + .replace(/\bBearer\s+[^\s,;"']+/gi, "Bearer [redacted]") + .replace(/\/(?:Users|home)\/[^\s"'<>]+/g, "[local path]") + .replace(/[A-Z]:\\Users\\[^\s"'<>]+/gi, "[local path]"); +} + +module.exports = { CHAT_LIMIT, AUDIO_LIMIT, ERROR_LIMIT, readResponseBytes, readResponseJson, returnedAudioUrl, audioDataUrl, redactServiceText }; diff --git a/src/preload.js b/src/preload.js index 599dde9..ed33c12 100644 --- a/src/preload.js +++ b/src/preload.js @@ -2,6 +2,15 @@ const { contextBridge, ipcRenderer } = require("electron"); contextBridge.exposeInMainWorld("desktopPet", { getAppState: () => ipcRenderer.invoke("get-app-state"), + getLive2DRuntime: () => ipcRenderer.invoke("get-live2d-runtime"), + importLive2DRuntime: () => ipcRenderer.invoke("import-live2d-runtime"), + openLive2DDownload: () => ipcRenderer.send("open-live2d-download"), + performModelAction: (action) => ipcRenderer.invoke("perform-model-action", action), + onModelAction: (callback) => { + const listener = (_event, action) => callback(action); + ipcRenderer.on("model-action", listener); + return () => ipcRenderer.off("model-action", listener); + }, setSettings: (patch) => ipcRenderer.send("set-settings", patch), getChatState: () => ipcRenderer.invoke("get-chat-state"), saveChatConfig: (patch) => ipcRenderer.invoke("save-chat-config", patch), diff --git a/src/quick-chat.html b/src/quick-chat.html index 74e9b12..794b1e5 100644 --- a/src/quick-chat.html +++ b/src/quick-chat.html @@ -2,6 +2,7 @@
+ Quick Companion Input diff --git a/src/renderer.js b/src/renderer.js index 1850a2d..6fc5459 100644 --- a/src/renderer.js +++ b/src/renderer.js @@ -104,6 +104,7 @@ function applyPetLayout() { function startAnimation() { window.clearInterval(animationTimer); + if (character.type === "live2d") return; const current = character.states[state] || character.states.idle; animationTimer = window.setInterval(() => { if (settings.expressionMode === "clickOnly" && !dragStart) { @@ -123,13 +124,17 @@ function setState(nextState) { if (!character.states[nextState]) return; if (state === nextState) return; state = nextState; + if (character.type === "live2d") { + if (settings.expressionMode === "automatic") window.DesktopPetModel?.expression(settings.persona?.live2dExpressions?.[nextState] ?? -1); + return; + } frameIndex = 0; startAnimation(); } function scheduleIdleBehavior() { window.clearTimeout(idleTimer); - if (settings.expressionMode !== "automatic" || conversationActive) return; + if (character.type === "live2d" || settings.expressionMode !== "automatic" || conversationActive) return; const delay = 22000 + Math.random() * 15000; idleTimer = window.setTimeout(() => { @@ -219,6 +224,7 @@ function applyAppState(nextAppState = {}) { expressionMode: nextAppState.settings?.expressionMode === "clickOnly" ? "clickOnly" : "automatic", interactionResponses: nextAppState.settings?.interactionResponses !== false, userName: nextAppState.settings?.persona?.userName || "", + persona: nextAppState.settings?.persona || {}, scale: Number(nextAppState.settings?.scale) || 1, alwaysOnTop: nextAppState.settings?.alwaysOnTop !== false, tts: { @@ -247,6 +253,18 @@ function applyAppState(nextAppState = {}) { talkButton.title = text("quick.toCharacter", { name: character.name }); document.documentElement.lang = activeLanguage; applyPetLayout(); + window.DesktopPetModel?.apply(character, settings, conversationActive || speechActive); + + if (character.type === "live2d") { + ++spriteLoadToken; + spriteImage = null; + ctx.clearRect(0, 0, canvas.width, canvas.height); + window.clearInterval(animationTimer); + window.clearTimeout(idleTimer); + if (characterChanged || modeChanged) resetAfterSettingsChange(); + scheduleStartupGreeting(); + return; + } if (characterChanged || !spriteImage) { const token = ++spriteLoadToken; @@ -278,6 +296,11 @@ function resetAfterSettingsChange() { temporaryToken += 1; state = "idle"; frameIndex = 0; + if (character.type === "live2d") { + window.DesktopPetModel?.expression(-1); + scheduleStartupGreeting(); + return; + } if (settings.expressionMode === "clickOnly") { window.clearTimeout(idleTimer); const currentIndex = character.staticExpressions.findIndex((expression) => expression.state === "idle" && expression.frame === 0); @@ -298,10 +321,11 @@ function respondToInteraction(kind) { : kind === "drop" ? ["tsundereProud", "happy", "waving", "idle"] : ["waving", "happy", "idle"]; const action = choices.find((name) => character.states[name]); if (action) playTemporary(action, 1400); + if (character.type === "live2d") window.DesktopPetModel?.touch(); // Touches stay local and quiet; they neither replace a visible reply nor queue up. if (bubbleVisible || performance.now() < interactionReadyAt) return; interactionReadyAt = performance.now() + 6000; - const style = character.id === "luna" ? "luna" : "default"; + const style = settings.persona?.relationship === "partner" ? "partner" : character.id === "luna" ? "luna" : "default"; const variant = interactionVariants[kind]++ % 2; const line = text(`pet.interaction.${style}.${kind}.${variant}`); showBubble(settings.userName ? text("pet.interaction.address", { name: settings.userName, line }) : line); @@ -310,11 +334,13 @@ function respondToInteraction(kind) { function handleClick(kind = "greet") { window.desktopPet.recordInteraction("click"); if (settings.expressionMode === "clickOnly") { + if (character.type === "live2d") { window.DesktopPetModel?.cycle(); return; } const [nextState, nextFrame] = nextStaticExpression(); setStaticExpression(nextState, nextFrame); } else { if (conversationActive || speechActive) return; if (settings.interactionResponses) { respondToInteraction(kind); return; } + if (character.type === "live2d") { window.DesktopPetModel?.touch(); return; } const nextState = nextClickState(); playTemporary(nextState); } @@ -437,6 +463,7 @@ function dismissBubble() { bubbleVisible = false; conversationActive = false; conversationAction = "idle"; + window.DesktopPetModel?.busy(speechActive); temporaryToken += 1; if (settings.expressionMode === "automatic" && !dragStart) setState("idle"); scheduleIdleBehavior(); @@ -509,6 +536,8 @@ function chooseTtsVoice() { function stopSpeech(status = "idle") { speechToken += 1; speechActive = false; + window.DesktopPetModel?.stopMouth(); + window.DesktopPetModel?.busy(conversationActive); if (speechId !== null) window.desktopPet.speechStateChanged({ id: speechId, status }); speechId = null; window.clearTimeout(speechWatchdog); @@ -527,6 +556,7 @@ async function speakText(text) { const token = speechToken; if (!settings.tts?.enabled || settings.tts.provider === "none" || !String(text || "").trim()) return; speechActive = true; + window.DesktopPetModel?.busy(true); window.clearTimeout(bubbleTimer); try { const id = await window.desktopPet.beginSpeech(speechGeneration); @@ -555,6 +585,7 @@ async function speakText(text) { activeAudio.onended = playNext; activeAudio.onerror = () => finishSpeech(token, true); await activeAudio.play(); + if (token === speechToken) window.DesktopPetModel?.attachAudio(activeAudio); if (token === speechToken) window.desktopPet.speechStateChanged({ id, status: "playing" }); } else { if (!("speechSynthesis" in window)) { finishSpeech(token, true); return; } @@ -603,6 +634,7 @@ function handlePetMessage(message = {}) { if (isChat) { if (!conversationActive || (!wasStreaming && bubbleStreaming)) conversationAction = "idle"; conversationActive = true; + window.DesktopPetModel?.busy(true); if (action && character.states[action]) conversationAction = action; window.clearTimeout(idleTimer); temporaryToken += 1; @@ -648,8 +680,16 @@ function loadSprite(spritePath) { } canvas.addEventListener("pointerdown", beginDrag); +canvas.addEventListener("pointermove", (event) => { + if (dragStart || character.type !== "live2d") return; + const bounds = canvas.getBoundingClientRect(); + window.DesktopPetModel?.gaze((event.clientX - bounds.left) / bounds.width * 0.7 - 0.35, + 0.25 - (event.clientY - bounds.top) / bounds.height * 0.5); +}); +canvas.addEventListener("pointerleave", () => window.DesktopPetModel?.gaze(0, 0)); canvas.addEventListener("dblclick", handleDoubleClick); canvas.addEventListener("pointerenter", () => { + if (character.type === "live2d") return; if (settings.expressionMode !== "automatic" || conversationActive || dragStart || performance.now() < hoverReadyAt) return; hoverReadyAt = performance.now() + 10000; if (state === "idle") playTemporary("waving", 900); diff --git a/src/settings.css b/src/settings.css index 5179f2c..44e59de 100644 --- a/src/settings.css +++ b/src/settings.css @@ -330,3 +330,13 @@ button:focus-visible { outline: 2px solid #316e74; outline-offset: 2px; } #import-preview { border-left: 3px solid #316e74; padding: 12px; } #import-status { font-size: 12px; } .settings-footer div { flex-shrink: 0; } +.live2d-badge { + display: grid; + place-items: center; + width: 56px; + min-height: 90px; + color: #286770; + background: #eff8f8; + font-size: 14px; + border-radius: 4px; +} diff --git a/src/settings.html b/src/settings.html index 1a3a8ad..d27f15f 100644 --- a/src/settings.html +++ b/src/settings.html @@ -2,6 +2,7 @@ + Desktop Pet Settings @@ -46,6 +47,7 @@

角色

+
+
@@ -76,6 +77,16 @@

角色

+

摸摸头

+
+ + +
+

轻轻碰一下

+
+ + +

回复表情

diff --git a/src/settings.js b/src/settings.js index 5cce8f3..8c3fd5c 100644 --- a/src/settings.js +++ b/src/settings.js @@ -130,7 +130,7 @@ async function mayLeave() { } async function importCharacter(kind) { - document.querySelector("#import-status").textContent = ""; + setImportStatus(""); try { const result = await window.desktopPet.previewCharacterImport(kind); if (result.cancelled) return; @@ -142,7 +142,13 @@ async function importCharacter(kind) { document.querySelector("#import-name").textContent = result.name; document.querySelector("#import-description").textContent = result.description; document.querySelector("#import-preview").hidden = false; - } catch { document.querySelector("#import-status").textContent = text("settings.importFailed"); } + } catch { setImportStatus("settings.importFailed"); } +} + +function setImportStatus(key) { + const status = document.querySelector("#import-status"); + status.dataset.statusKey = key; + status.textContent = key ? text(key) : ""; } const DEFAULT_CUSTOM_BODY = "{\"text\":\"{{text}}\"}"; @@ -282,6 +288,7 @@ function refreshLanguageOptions(selectedValue = "system") { } function applyStaticTranslations() { + setImportStatus(document.querySelector("#import-status").dataset.statusKey || ""); document.documentElement.lang = activeLanguage; document.title = text("window.settingsTitle"); document.querySelector("h1").textContent = text("settings.title"); @@ -516,8 +523,15 @@ function renderLive2D(character) { document.querySelector("#live2d-panel").hidden = character.type !== "live2d"; if (character.type !== "live2d") return; document.querySelector("#live2d-gaze").checked = config.persona?.live2dGaze !== false; + document.querySelector("#live2d-idle").checked = config.persona?.live2dIdle !== false; const names = character.expressions || []; fillModelExpressions(document.querySelector("#live2d-expression"), names); + for (const kind of ["head", "greet"]) { + const touch = config.persona?.live2dTouches?.[kind]; + const index = touch?.expression ?? -1; + fillModelExpressions(document.querySelector(`#live2d-touch-${kind}`), names, index < names.length ? index : -1); + fillModelMotions(document.querySelector(`#live2d-motion-touch-${kind}`), character.motions, touch?.motion, true); + } for (const mood of ["happy", "shy", "review", "failed"]) { const index = config.persona?.live2dExpressions?.[mood] ?? -1; fillModelExpressions(document.querySelector(`#live2d-${mood}`), names, index < names.length ? index : -1); @@ -707,6 +721,11 @@ function readConfigForm(includeEmptyKey = false) { background: personaBackgroundEl.value.trim(), extraRules: personaExtraRulesEl.value.trim(), live2dGaze: document.querySelector("#live2d-gaze").checked, + live2dIdle: document.querySelector("#live2d-idle").checked, + live2dTouches: Object.fromEntries(["head", "greet"].map((kind) => [kind, { + expression: Number(document.querySelector(`#live2d-touch-${kind}`).value || -1), + motion: selectedReplyMotion(`touch-${kind}`), + }])), live2dExpressions: Object.fromEntries(["happy", "shy", "review", "failed"].map((mood) => [mood, Number(document.querySelector(`#live2d-${mood}`).value || -1)])), live2dMotions: Object.fromEntries(["happy", "shy", "review", "failed"].map((mood) => [mood, selectedReplyMotion(mood)])), @@ -995,8 +1014,8 @@ document.querySelector("#confirm-import").addEventListener("click", async () => if (!result.ok) throw new Error(); applyChatState(result); document.querySelector("#import-preview").hidden = true; - document.querySelector("#import-status").textContent = text("settings.imported"); - } catch { document.querySelector("#import-status").textContent = text("settings.importFailed"); } + setImportStatus("settings.imported"); + } catch { setImportStatus("settings.importFailed"); } }); document.querySelector("#remove-character").addEventListener("click", async () => { if (!(await mayLeave())) return; diff --git a/tests/live2d-bridge.test.js b/tests/live2d-bridge.test.js index b62aa8a..c681dc9 100644 --- a/tests/live2d-bridge.test.js +++ b/tests/live2d-bridge.test.js @@ -26,7 +26,7 @@ function setup() { vm.runInContext(fs.readFileSync(path.join(__dirname, "../src/live2d-bridge.js"), "utf8"), context); return { api: context.window.DesktopPetModel, sent, events, connections: () => connections, resume: () => resume(), - message: type => events.message({ source: frame.contentWindow, origin: "pet-live2d://viewer", data: { channel: "desktop-pet-model", type } }) }; + message: (type, extra = {}) => events.message({ source: frame.contentWindow, origin: "pet-live2d://viewer", data: { channel: "desktop-pet-model", type, ...extra } }) }; } test("model readiness replays only the latest expression and current attention", async () => { @@ -40,6 +40,37 @@ test("model readiness replays only the latest expression and current attention", assert.equal(ui.sent.at(-1).state, "thinking"); }); +test("hit queries accept only known regions and are cancelled on replacement or character switch", async () => { + const ui = setup(); + await ui.api.apply({ id: "sample", type: "live2d" }, { expressionMode: "automatic" }); + ui.message("boot"); ui.message("loaded"); + let first = ui.api.locate(0.5, 0.2); + ui.message("location", { request: ui.sent.at(-1).request, kind: "head" }); + assert.equal(await first, "head"); + first = ui.api.locate(0.5, 0.2); + const second = ui.api.locate(0.5, 0.8); + assert.equal(await first, null); + ui.message("location", { request: ui.sent.at(-1).request, kind: "unknown" }); + assert.equal(await second, null); + const pending = ui.api.locate(0.5, 0.2); + await ui.api.apply({ id: "sprite" }, {}); + assert.equal(await pending, null); +}); + +test("drag interruption and quiet-idle settings survive ordinary state broadcasts", async () => { + const ui = setup(); + const character = { id: "sample", type: "live2d" }; + const settings = { expressionMode: "automatic", persona: { live2dIdle: false, live2dTouches: { head: { expression: 1 } } } }; + await ui.api.apply(character, settings); ui.message("boot"); ui.message("loaded"); + ui.api.dragging(true); + await ui.api.apply(character, settings); + assert.equal(ui.sent.at(-1).dragging, true); + assert.equal(ui.sent.at(-1).idle, false); + assert.equal(ui.sent.at(-1).touches.head.expression, 1); + ui.api.dragging(false); + assert.equal(ui.sent.at(-1).dragging, false); +}); + test("stopping or switching characters during audio resume cannot reconnect old speech", async () => { for (const switchCharacter of [false, true]) { const ui = setup(); diff --git a/tests/live2d-import.test.js b/tests/live2d-import.test.js index e5229b5..d10ea05 100644 --- a/tests/live2d-import.test.js +++ b/tests/live2d-import.test.js @@ -64,6 +64,27 @@ test("Live2D rejects missing resources, symlinked directories and malformed PNGs assert.throws(() => readLive2DPack(root)); }); +test("native hit areas survive import with unique names and no unrelated metadata", (t) => { + const { root } = fixture(t, raw => { raw.HitAreas = [ + { Id: "HitAreaHead", Name: "", url: "https://example.invalid" }, + { Id: "HitAreaBody", Name: "" }, { Id: "Hair", Name: "Head" }, { Id: "Hair2", Name: "Head" }, + { Id: "Hands", Name: "__proto__" }, + ]; }); + const areas = JSON.parse(readLive2DPack(root).files["model.model3.json"]).HitAreas; + assert.equal(areas.length, 5); + assert.equal(new Set(areas.map(area => area.Name)).size, 5); + assert.equal(areas[0].Name, "HitAreaHead 1"); + assert.equal(areas[1].Name, "HitAreaBody 2"); + assert.equal(areas[0].url, undefined); + assert.equal(areas.some(area => area.Name === "__proto__"), false); +}); + +test("malformed or unbounded hit areas are rejected", t => { + for (const areas of [null, {}, [null], [{ Id: "" }], [{ Id: "x".repeat(129) }], Array(65).fill({ Id: "Head" })]) { + assert.throws(() => readLive2DPack(fixture(t, raw => { raw.HitAreas = areas; }).root), /invalid_hit_areas/); + } +}); + test("Live2D ZIP rejects ambiguous models, traversal and case-colliding paths", (t) => { const { root, files } = fixture(t); const target = path.join(root, "bad.zip"); diff --git a/tests/live2d-runtime.test.js b/tests/live2d-runtime.test.js index c2f002e..75d8c64 100644 --- a/tests/live2d-runtime.test.js +++ b/tests/live2d-runtime.test.js @@ -3,7 +3,7 @@ const assert = require("node:assert/strict"); const fs = require("node:fs"); const path = require("node:path"); const { createHash } = require("node:crypto"); -const { loadMain } = require("./helpers"); +const { loadMain, loadRenderer } = require("./helpers"); const { loadPet } = require("./pet-helpers"); test("vendored display bundles match the pinned upstream releases and omit Core/models", () => { @@ -27,12 +27,69 @@ test("model expression mappings and gaze normalize without enabling affection or test("Live2D click-only advances once without scheduling sprite actions or network calls", () => { const pet = loadPet(); - pet.run(`globalThis.modelCalls=[]; window.DesktopPetModel={apply(){},expression(){},stopMouth(){},busy(){},cycle(){modelCalls.push("cycle")}}; + pet.run(`globalThis.modelCalls=[]; window.DesktopPetModel={apply(){},expression(){},stopMouth(){},busy(){},dragging(){},cycle(){modelCalls.push("cycle")}}; applyAppState({settings:{expressionMode:"clickOnly"},activeCharacter:{id:"imported-fixture",type:"live2d",states:{idle:{row:0,frames:1,interval:1000}}}}); handleClick(); handleDoubleClick(); handleLongPress(); scheduleIdleBehavior();`); assert.deepEqual(JSON.parse(pet.run('JSON.stringify(modelCalls)')), ["cycle"]); }); +test("slow double-clicks advance once even when pointer events have no click count", () => { + const pet = loadPet(); + pet.run(`globalThis.cycles=0; window.DesktopPetModel={dragging(){},cycle(){cycles++}}; + character={...character,type:"live2d"}; settings.expressionMode="clickOnly";`); + for (const detail of [1, 2]) { + pet.run('clickOnlyReadyAt=0; beginDrag({button:0,clientX:96,clientY:100,screenX:100,screenY:100})'); + pet.events.mousedown({ detail }); + pet.run('endDrag({detail:0})'); + } + assert.equal(pet.run('cycles'), 1); +}); + +test("touch mappings validate indices, preserve motion group names, and keep quiet idle optional", () => { + const app = loadMain(); + const persona = app.run(`normalizeSettings({persona:{live2dIdle:false,live2dTouches:{ + head:{expression:0,motion:{group:"",index:0}},greet:{expression:64,motion:{group:"Tap",index:-1}} + }}}).persona`); + assert.equal(persona.live2dIdle, false); + assert.deepEqual(JSON.parse(JSON.stringify(persona.live2dTouches)), { + head: { expression: 0, motion: { group: "", index: 0 } }, greet: { expression: -1, motion: null }, + }); + assert.equal(app.run('normalizeSettings({}).persona.live2dIdle'), true); +}); + +test("a delayed hit test cannot trigger a touch after dragging, mode changes or focus loss", async () => { + for (const interrupt of ['cancelDrag()', 'settings.expressionMode="clickOnly"', 'dragStart={}']) { + const pet = loadPet(); + pet.run(`globalThis.touches=[]; window.DesktopPetModel={dragging(){},locate(){return new Promise(resolve=>globalThis.resolveHit=resolve)},touch(kind){touches.push(kind)}}; + character={...character,type:"live2d"}; scheduleSingleClick("greet",{x:0.5,y:0.2});`); + pet.fireTimer(pet.run('clickTimer')); + pet.run(interrupt); + pet.run('resolveHit("head")'); + await new Promise(resolve => setImmediate(resolve)); + assert.equal(pet.run('touches.length'), 0); + } +}); + +test("native head hits select head responses and transparent hits do nothing", async () => { + for (const hit of ["head", "greet", null]) { + const pet = loadPet(); + pet.context.hit = hit; + pet.run(`globalThis.touches=[]; window.DesktopPetModel={locate:async()=>hit,touch(kind){touches.push(kind)}}; + character={...character,type:"live2d"}; scheduleSingleClick("greet",{x:0.5,y:0.2});`); + pet.fireTimer(pet.run('clickTimer')); + await new Promise(resolve => setImmediate(resolve)); + assert.deepEqual(JSON.parse(pet.run('JSON.stringify(touches)')), hit ? [hit] : []); + } +}); + +test("import feedback follows settings language changes", () => { + const ui = loadRenderer("settings.js"); + ui.run('setImportStatus("settings.imported"); activeLanguage="en-US"; applyStaticTranslations()'); + assert.match(ui.nodes.get("#import-status").textContent, /Character/); + ui.run('activeLanguage="ja-JP"; applyStaticTranslations()'); + assert.equal(ui.nodes.get("#import-status").textContent, require("../src/i18n").t("settings.imported", {}, "ja-JP")); +}); + test("partner touch phrases are opt-in, local and leave affection unchanged", () => { const pet = loadPet(); pet.run('settings.persona = {relationship:"partner"}; settings.userName="Alex"; respondToInteraction("head")'); diff --git a/tests/live2d-smoke.cjs b/tests/live2d-smoke.cjs index 121cc99..0ed084d 100644 --- a/tests/live2d-smoke.cjs +++ b/tests/live2d-smoke.cjs @@ -74,12 +74,24 @@ async function run() { assert.equal(await frame.evaluate(() => typeof window.desktopPet), "undefined"); assert.equal(await frame.evaluate(() => typeof window.require), "undefined"); await frame.evaluate(() => { + window.modelCommands = []; + window.addEventListener("message", event => { if (event.data?.channel === "desktop-pet-model") modelCommands.push(event.data.type); }); const original = PIXI.live2d.Live2DModel.from; PIXI.live2d.Live2DModel.from = async (...args) => { window.testModel = await original.apply(PIXI.live2d.Live2DModel, args); return window.testModel; }; }); await pet.evaluate((id) => { document.querySelector("iframe").contentWindow.postMessage({ channel: "desktop-pet-model", type: "load", id }, "pet-live2d://viewer"); window.modelEvents = []; + window.expressionSources = []; + window.pointerEvents = []; + for (const type of ["pointerdown", "mousedown", "pointerup", "mouseup", "click", "dblclick"]) { + document.querySelector("#pet").addEventListener(type, event => pointerEvents.push({ type, detail: event.detail, time: Math.round(performance.now()) })); + } + const originalExpression = window.DesktopPetModel.expression; + window.DesktopPetModel.expression = index => { + expressionSources.push({ index, stack: new Error().stack.split("\n").slice(1, 5).map(line => line.replace(/file:\/\/[^)]+\//g, "")) }); + originalExpression(index); + }; window.addEventListener("message", (event) => { if (event.data?.channel === "desktop-pet-model") modelEvents.push(event.data); }); }, id); await frame.waitForFunction(() => window.testModel?.internalModel); @@ -118,7 +130,44 @@ async function run() { assert.equal(after.length, before + 1, "one click, one expression"); assert.equal(after.at(-1).index, 0); await pet.waitForTimeout(1200); - assert.equal(await pet.evaluate(() => modelEvents.filter((item) => item.type === "expression").length), after.length); + const heldExpressions = await pet.evaluate(() => modelEvents.filter(item => item.type === "expression")); + assert.equal(heldExpressions.length, after.length, JSON.stringify({ heldExpressions, commands: await frame.evaluate(() => modelCommands), sources: await pet.evaluate(() => expressionSources) })); + await pet.locator("#pet").dblclick(); + await pet.waitForTimeout(600); + assert.equal(await pet.evaluate(() => modelEvents.filter(item => item.type === "expression").length), after.length + 1, "double-click adds no second expression"); + const slowClickBox = await pet.locator("#pet").boundingBox(); + const slowClickX = slowClickBox.x + slowClickBox.width / 2; + const slowClickY = slowClickBox.y + slowClickBox.height / 2; + await pet.mouse.move(slowClickX, slowClickY); + await pet.mouse.down({ clickCount: 1 }); await pet.mouse.up({ clickCount: 1 }); + await pet.waitForTimeout(320); + await pet.mouse.down({ clickCount: 2 }); await pet.mouse.up({ clickCount: 2 }); + await pet.waitForTimeout(600); + assert.equal(await pet.evaluate(() => modelEvents.filter(item => item.type === "expression").length), after.length + 2, + JSON.stringify({ reason: "slow double-click adds no second expression either", events: await pet.evaluate(() => pointerEvents), expressions: await pet.evaluate(() => modelEvents.filter(item => item.type === "expression")), sources: await pet.evaluate(() => expressionSources) })); + const manualBeforeHold = await pet.evaluate(() => modelEvents.filter(item => item.type === "expression").length); + await pet.mouse.down(); await pet.waitForTimeout(650); await pet.mouse.up(); + await pet.waitForTimeout(400); + assert.equal(await pet.evaluate(() => modelEvents.filter(item => item.type === "expression").length), manualBeforeHold, "long hold never advances manual expressions"); + assert.equal(await pet.evaluate(() => settings.scale), 2, "double-click and hold never resize the pet"); + await app.evaluate(({ screen }) => { + globalThis.testCursor = { x: 300, y: 300 }; + globalThis.originalCursorReader = screen.getCursorScreenPoint; + screen.getCursorScreenPoint = () => globalThis.testCursor; + }); + try { + await pet.mouse.down(); + await pet.waitForTimeout(50); + await app.evaluate(() => { globalThis.testCursor = { x: 320, y: 320 }; }); + await pet.waitForFunction(() => didDrag === true); + await pet.mouse.up(); + await pet.waitForFunction(() => dragStart === null && didDrag === false); + await pet.waitForTimeout(350); + assert.equal(await pet.evaluate(() => modelEvents.filter(item => item.type === "expression").length), manualBeforeHold, "manual dragging preserves the selected native expression"); + assert.equal(await pet.evaluate(() => modelEvents.filter(item => item.type === "touch").length), 0, "dragging never turns into a tap"); + } finally { + await app.evaluate(({ screen }) => { screen.getCursorScreenPoint = globalThis.originalCursorReader; }); + } await pet.screenshot({ path: path.join(output, "model-manual-200.png") }); await pet.evaluate(() => window.desktopPet.setSettings({ expressionMode: "automatic", scale: 0.75 })); await pet.waitForTimeout(600); @@ -145,6 +194,62 @@ async function run() { await settings.screenshot({ path: path.join(output, "settings-reply-gestures.png") }); await settings.locator("#save-settings").click(); await pet.waitForFunction(() => settings.persona.live2dExpressions.happy === 1); + await settings.locator("#live2d-idle").uncheck(); + await settings.locator("#live2d-gaze").uncheck(); + await settings.locator("#live2d-touch-head").selectOption("0"); + await settings.locator("#live2d-touch-greet").selectOption("2"); + await settings.locator("#save-settings").click(); + await pet.waitForFunction(() => settings.persona.live2dIdle === false && settings.persona.live2dTouches.head.expression === 0); + await settings.locator("#live2d-touch-head").scrollIntoViewIfNeeded(); + await settings.screenshot({ path: path.join(output, "settings-touch-responses.png") }); + await pet.evaluate(() => { dismissBubble(); window.DesktopPetModel.expression(-1); }); + await pet.waitForTimeout(600); + // Probe the same isolated bridge used by pointer events, including models with no hit areas. + const touchPoints = await pet.evaluate(async () => { + const points = {}; + for (const y of [0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]) { + for (const x of [0.5, 0.4, 0.6]) { + const kind = await window.DesktopPetModel.locate(x, y); + if (kind && !points[kind]) points[kind] = { x, y }; + } + } + return points; + }); + assert.ok(touchPoints.head && touchPoints.greet, "head and body hit regions are reachable"); + const clickPoint = async point => { + const box = await pet.locator("#pet").boundingBox(); + await pet.locator("#pet").click({ position: { x: point.x * box.width, y: point.y * box.height } }); + }; + await clickPoint(touchPoints.head); + await pet.waitForFunction(() => modelEvents.filter(item => item.type === "touch").at(-1)?.kind === "head"); + await pet.waitForFunction(() => modelEvents.filter(item => item.type === "expression").at(-1)?.index === 0); + await pet.screenshot({ path: path.join(output, "head-pat.png") }); + await clickPoint(touchPoints.head); + await pet.waitForTimeout(350); + assert.equal(await pet.evaluate(() => modelEvents.filter(item => item.type === "touch").length), 1, "rapid pats never stack"); + await pet.waitForFunction(() => modelEvents.filter(item => item.type === "expression").at(-1)?.index === -1); + await pet.waitForTimeout(400); + await clickPoint(touchPoints.greet); + await pet.waitForFunction(() => modelEvents.filter(item => item.type === "touch").at(-1)?.kind === "greet"); + await pet.waitForFunction(() => modelEvents.filter(item => item.type === "expression").at(-1)?.index === 2); + await pet.locator("#talk").click(); + await pet.waitForFunction(() => modelEvents.filter(item => item.type === "expression").at(-1)?.index === -1); + await pet.locator("#companion-close").click(); + await pet.waitForTimeout(2400); + await clickPoint({ x: 0.001, y: 0.001 }); + await pet.waitForTimeout(450); + assert.equal(await pet.evaluate(() => modelEvents.filter(item => item.type === "touch").length), 2, "empty corners do not trigger interaction"); + assert.equal(requests, 0, "touch interactions never call the LLM"); + for (const language of ["ja-JP", "zh-CN", "en-US"]) { + await settings.evaluate(language => window.desktopPet.saveChatConfig({ language }), language); + await settings.waitForFunction(language => document.documentElement.lang === language, language); + await settings.locator("#live2d-motion-touch-greet").scrollIntoViewIfNeeded(); + assert.equal(await settings.locator("#live2d-touch-head").inputValue(), "0"); + assert.equal(await settings.locator("#live2d-touch-greet").inputValue(), "2"); + assert.equal(await settings.locator("#live2d-idle").isChecked(), false); + assert.equal(await settings.evaluate(() => document.documentElement.scrollWidth > innerWidth), false); + await settings.screenshot({ path: path.join(output, `touch-settings-${language}.png`) }); + } await settings.evaluate((endpoint) => window.desktopPet.saveChatConfig({ assistant: { baseUrl: `${endpoint}/v1`, model: "local-test", stream: false }, tts: { enabled: true, provider: "custom", endpoint: `${endpoint}/tts`, customBodyTemplate: '{"text":"{{text}}"}' }, @@ -206,7 +311,7 @@ async function run() { await pet.waitForFunction(() => !document.querySelector("iframe") && spriteImage && character.id === "luna"); assert.equal(await pet.evaluate(() => ctx.getImageData(0, 0, 768, 832).data.some((value, index) => index % 4 === 3 && value > 0)), true); assert.deepEqual(errors, []); - console.log("PASS: native sample loading, isolated frame, blink, breath, gaze, manual expression, motion, inline draft/submit/failure/cancel, history sync, chat expression, audio-driven mouth/stop, scaling, sprite fallback; isolated local LLM/TTS only."); + console.log("PASS: native sample loading, isolated frame, blink, breath, gaze, manual expression, motion, head/body touch mapping/restoration/interruption, empty hit rejection, inline draft/submit/failure/cancel, history sync, chat expression, audio-driven mouth/stop, scaling, sprite fallback; isolated local LLM/TTS only."); } finally { await app.evaluate(({ app }) => app.exit(0)); await app.close(); diff --git a/tests/live2d-viewer.test.js b/tests/live2d-viewer.test.js index dbafe3e..44f98fd 100644 --- a/tests/live2d-viewer.test.js +++ b/tests/live2d-viewer.test.js @@ -6,26 +6,34 @@ const vm = require("node:vm"); const rig = require("../src/live2d/rig"); async function viewer() { - const events = {}, updates = {}, messages = [], motions = [], values = {}; + const events = {}, updates = {}, messages = [], motions = [], values = {}, expressions = []; let now = 100, stops = 0; + let alpha = 255; const internal = { width: 100, height: 200, coreModel: { getModel: () => ({ parameters: { ids: ["PARAM_ANGLE_Z", "PARAM_MOUTH_OPEN_Y"] } }), - setParameterValueById: (id, value) => { values[id] = value; }, addParameterValueById() {} }, + setParameterValueById: (id, value) => { values[id] = value; }, addParameterValueById: (id, value) => { values[id] = value; } }, breath: { getParameters: () => [] }, - motionManager: { groups: {}, stopAllMotions: () => { stops++; } }, + motionManager: { groups: {}, stopAllMotions: () => { stops++; }, on: (name, callback) => { events[name] = callback; }, + expressionManager: { defaultExpression: {}, resetExpression: () => expressions.push(-1), + setExpression: async index => { expressions.push(index); return true; } } }, + hitAreas: { Head: {}, Body: {} }, focusController: { focus() {} }, on: (event, callback) => { updates[event] = callback; }, }; const model = { internalModel: internal, scale: { set() {} }, anchor: { set() {} }, position: { set() {} }, - destroy() {}, update() {}, motion: async (group, index) => { motions.push({ group, index }); return true; } }; + destroy() {}, update() {}, motion: async (group, index) => { motions.push({ group, index }); return true; }, + hitTest: (x, y) => x < 10 ? [] : y < 150 ? ["Head", "Body"] : ["Body"] }; const parent = { postMessage: message => messages.push(message) }; const context = vm.createContext({ parent, innerWidth: 200, innerHeight: 400, devicePixelRatio: 1, performance: { now: () => now }, - document: { querySelector: () => ({}), addEventListener() {} }, + document: { hidden: false, querySelector: () => ({ width: 200, height: 400 }), addEventListener: (name, callback) => { events[name] = callback; } }, window: { Live2DCubismCore: {}, DesktopPetRig: { ...rig, measure: () => ({ width: 100, height: 200 }) }, addEventListener: (name, callback) => { events[name] = callback; } }, - fetch: async () => ({ json: async () => ({ FileReferences: { Motions: { Tap: [{}, {}] } } }) }), + fetch: async () => ({ json: async () => ({ FileReferences: { Expressions: [{ Name: "Smile" }, { Name: "Blush" }], Motions: { Tap: [{}, {}], Idle: [{}] } } }) }), PIXI: { Application: class { - constructor() { this.renderer = { resize() {} }; this.stage = { addChild() {} }; this.ticker = { add() {} }; } + constructor() { + this.renderer = { resize() {}, gl: { readPixels: (x, y, w, h, format, type, pixel) => { pixel[3] = alpha; } } }; + this.stage = { addChild() {} }; this.ticker = { add() {}, stop() {}, start() {} }; + } }, live2d: { Live2DModel: { from: async () => model } } }, }); context.window.PIXI = context.PIXI; @@ -34,7 +42,9 @@ async function viewer() { data: { channel: "desktop-pet-model", id: "imported-123456789012345678901234", type, ...extra } }); send("load"); await new Promise(resolve => setImmediate(resolve)); assert.ok(messages.some(message => message.type === "loaded")); - return { send, motions, values, stops: () => stops, advance: milliseconds => { now += milliseconds; }, tick: () => updates.beforeModelUpdate() }; + return { send, motions, values, messages, expressions, events, context, stops: () => stops, + setAlpha: value => { alpha = value; }, internal, model, + advance: milliseconds => { now += milliseconds; }, tick: () => updates.beforeModelUpdate() }; } test("reply gestures are bounded and unavailable in click-only mode", async () => { @@ -50,6 +60,80 @@ test("reply gestures are bounded and unavailable in click-only mode", async () = assert.equal(ui.motions.length, 2); }); +const flush = () => new Promise(resolve => setImmediate(resolve)); + +test("head pats ease in and out, do not stack, and restore the previous expression", async () => { + const ui = await viewer(); + ui.send("expression", { index: 0 }); await flush(); + ui.send("options", { touches: { head: { expression: 1 } } }); + ui.send("touch", { kind: "head" }); await flush(); + assert.equal(ui.expressions.at(-1), 1); + ui.tick(); assert.ok(Math.abs(ui.values.PARAM_ANGLE_Z) < 0.001); + ui.advance(1100); ui.tick(); assert.equal(ui.values.PARAM_ANGLE_Z, -5); + ui.send("touch", { kind: "head" }); + assert.equal(ui.messages.filter(message => message.type === "touch").length, 1); + ui.advance(1100); ui.tick(); await flush(); + assert.equal(ui.expressions.at(-1), 0); + assert.ok(Math.abs(ui.values.PARAM_ANGLE_Z) < 0.001); +}); + +test("touch expressions cannot overwrite a newer reply, drag or manual selection", async () => { + for (const interrupt of ["expression", "drag", "manual", "presence"]) { + const ui = await viewer(); + ui.send("options", { touches: { head: { expression: 1 } } }); + ui.send("touch", { kind: "head" }); await flush(); + if (interrupt === "expression") ui.send("expression", { index: 0 }); + if (interrupt === "drag") ui.send("options", { dragging: true }); + if (interrupt === "manual") ui.send("options", { automatic: false }); + if (interrupt === "presence") ui.send("presence", { state: "attentive" }); + await flush(); + const count = ui.expressions.length; + ui.advance(5000); ui.tick(); await flush(); + assert.equal(ui.expressions.length, count); + assert.equal(ui.expressions.at(-1), interrupt === "expression" ? 0 : -1); + } +}); + +test("body touches use their own motion, while quiet idle never suppresses requested gestures", async () => { + const ui = await viewer(); + ui.send("options", { idle: false, touches: { greet: { motion: { group: "Tap", index: 1 } } } }); + ui.advance(90000); ui.tick(); assert.equal(ui.motions.length, 0); + ui.send("touch", { kind: "greet" }); ui.tick(); + assert.deepEqual(ui.motions, [{ group: "Tap", index: 1 }]); + assert.equal(ui.values.PARAM_ANGLE_Z, undefined, "native gestures have no additional artificial tilt"); + ui.send("options", { idle: true }); ui.advance(60000); ui.tick(); + assert.equal(ui.motions.at(-1).group, "Idle"); +}); + +test("hit tests prefer native head areas and reject blank or malformed coordinates", async () => { + const ui = await viewer(); + for (const [x, y, kind] of [[0.5, 0.2, "head"], [0.5, 0.8, "greet"], [0, 0, null], [NaN, 0, null], [1, 1, null]]) { + ui.send("locate", { x, y, request: 1 }); + assert.equal(ui.messages.at(-1).kind, kind); + } + ui.setAlpha(0); ui.send("locate", { x: 0.5, y: 0.2, request: 2 }); + assert.equal(ui.messages.at(-1).kind, null, "transparent pixels inside native bounds do not react"); + ui.setAlpha(255); + ui.internal.hitAreas = { localized: { id: "HitAreaHead" } }; + ui.model.hitTest = () => ["localized"]; + ui.send("locate", { x: 0.5, y: 0.2, request: 3 }); + assert.equal(ui.messages.at(-1).kind, "head", "drawable IDs resolve non-English names"); + ui.internal.hitAreas = {}; + ui.send("locate", { x: 0.5, y: 0.8, request: 4 }); + assert.equal(ui.messages.at(-1).kind, "greet", "models without native areas use visible fallback regions"); +}); + +test("hiding cancels transient gestures and resuming never launches a queued idle motion", async () => { + const ui = await viewer(); + ui.send("options", { touches: { head: { expression: 1 } } }); + ui.send("touch", { kind: "head" }); await flush(); + ui.context.document.hidden = true; ui.events.visibilitychange(); await flush(); + assert.equal(ui.expressions.at(-1), -1); + ui.advance(120000); + ui.context.document.hidden = false; ui.events.visibilitychange(); ui.tick(); + assert.equal(ui.motions.length, 0); +}); + test("speech preserves a reply gesture while the next user request interrupts it", async () => { const ui = await viewer(); ui.send("presence", { state: "thinking" }); From f0b0503b9a12fc30b6b064c9fbc380d3e45a9f99 Mon Sep 17 00:00:00 2001 From: TonyNa-code <278977922+TonyNa-code@users.noreply.github.com> Date: Mon, 26 Oct 2026 18:56:58 +0800 Subject: [PATCH 4/7] Preserve vendored runtime bytes on Windows checkout --- .gitattributes | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..7b19f2d --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +# Preserve the exact bytes checked against upstream SHA-256 hashes. +/src/live2d/vendor/pixi.min.js -text +/src/live2d/vendor/cubism4.min.js -text From 4bd93332979e569c1972c8e751cf5d02e51e2859 Mon Sep 17 00:00:00 2001 From: TonyNa-code <278977922+TonyNa-code@users.noreply.github.com> Date: Mon, 26 Oct 2026 19:41:20 +0800 Subject: [PATCH 5/7] Expose pet controls beside the character --- docs/live2d.md | 6 ++++++ src/i18n.js | 3 +++ src/index.html | 1 + src/renderer.js | 4 +++- src/styles.css | 1 + tests/bubble-controls.test.js | 14 +++++++++++++- tests/electron-smoke.cjs | 22 ++++++++++++++++++++-- tests/live2d-smoke.cjs | 17 +++++++++++++++++ tests/pet-helpers.js | 4 ++-- 9 files changed, 66 insertions(+), 6 deletions(-) diff --git a/docs/live2d.md b/docs/live2d.md index 32c2e7e..e488bc7 100644 --- a/docs/live2d.md +++ b/docs/live2d.md @@ -30,6 +30,8 @@ For a closer companion tone, choose **Relationship > Partner**, set your preferr The speech icon opens a small input beside the character. Enter sends your message and folds the input away; replies appear just above the character. Escape closes the input without losing its draft. The book icon opens the full conversation, sharing the same draft and history. A failed request keeps your unsent text for another attempt. +The menu button beside the speech icon opens character selection, size, full chat, chat settings, and **Quit**. The same menu is available by right-clicking the character. + In automatic mode, a Live2D character gently centers its gaze while you type or wait for a reply. Its own blink and breath continue; random idle gestures wait until the conversation settles. Click expression mode keeps the expression you selected. External voice playback has a compact stop/replay control beside the character. Under **Reply gestures**, you can also assign a native motion to each reply mood. All start with **No gesture**. A completed reply can play one selected motion, not one per streamed text chunk. Gestures are spaced apart during quick exchanges, and a new message interrupts the previous gesture. Starting voice playback does not cancel the current reply gesture. Click expression mode disables reply gestures. @@ -74,6 +76,8 @@ Chat and spoken text still go to the services you explicitly configure. Returned 点人物旁的对话图标即可展开小输入框,按回车发送后自动收起,回复显示在人物上方。按 Esc 可收起并保留草稿;点书本图标可看完整聊天记录,两处共用草稿。请求失败时也会保留未发送的文字。自动模式下,输入和等待回复时人物会轻轻看向你,保持眨眼、呼吸,暂缓待机动作。点击模式不改变手动选中的表情。朗读的停止、重播按钮在人物身旁。 +对话图标旁的菜单按钮可以切换角色、调整大小、打开完整聊天和对话设置,或选择 **退出**。右键点击人物也能打开同一个菜单。 + 在 **回复动作** 中可以为各个情绪选择模型自带动作,默认均不播放。一条完整回复最多触发一次,逐字输出时不会重复触发;连续短回复也不会让动作连着播放。开始朗读会保留当前回复动作,发出新消息则会中止上一动作。点击表情模式不播放回复动作。 支持 Cubism 3/4 导出的模型、PNG、表情、动作、物理和姿态文件。不能把一张立绘自动变成 Live2D,也不支持 Cubism 2、编辑工程 `.cmo3`、PSD、VRM 或 Cubism 5.3 的扩展混合模式。单包上限 128 MiB、256 文件、8 张纹理,单张最长边 8192,纹理总像素不超过 6400 万,单个 JSON 不超过 2 MiB。 @@ -102,6 +106,8 @@ Chat and spoken text still go to the services you explicitly configure. Returned キャラクター横の会話アイコンで小さな入力欄が開きます。Enter で送信すると閉じ、返答はキャラクターのすぐ上に表示されます。Esc で閉じても下書きは残ります。本のアイコンから開く会話履歴とも下書きを共有します。送信失敗時も入力内容は保持されます。自動モードでは入力中や返答待ちに視線をそっと中央に戻し、まばたきと呼吸を続けます。クリック表情モードでは選んだ表情を保ちます。音声の停止・再生はキャラクター横の小さなボタンで操作できます。 +会話アイコン横のメニューボタンから、キャラクター・サイズの変更、チャット画面、会話設定、**終了**を選べます。キャラクターを右クリックしても同じメニューが開きます。 + **返答時のモーション** では、感情ごとにモデルの動作を選べます。初期値はすべて「モーションなし」です。一つの返答につき一度だけ再生し、文字の逐次表示や短い返答の連続で動作を繰り返しません。読み上げ開始時も動作を保ち、新しいメッセージで前の動作を中断します。クリック表情モードでは再生しません。 Cubism 3/4 の書き出しモデルに対応します。Cubism 2、`.cmo3` 編集ファイル、PSD、VRM、Cubism 5.3 の拡張ブレンドは非対応です。128 MiB・256 ファイル・PNG 8 枚まで、各辺 8192 ピクセル以下、合計 6400 万ピクセル以下、JSON は一つ 2 MiB 以下です。 diff --git a/src/i18n.js b/src/i18n.js index 8238f7b..81afb52 100644 --- a/src/i18n.js +++ b/src/i18n.js @@ -126,6 +126,7 @@ "voice.ready": "最近的回复", "voice.failed": "语音未能播放", "pet.talk": "对话", + "pet.menu": "桌宠菜单", "quick.toCharacter": "和{name}说点什么…", "quick.history": "记录", "quick.responding": "正在回应…", @@ -504,6 +505,7 @@ "voice.ready": "Latest reply", "voice.failed": "Voice unavailable", "pet.talk": "Talk", + "pet.menu": "Pet menu", "quick.toCharacter": "Talk to {name}…", "quick.history": "History", "quick.responding": "Replying…", @@ -882,6 +884,7 @@ "voice.ready": "直近の返信", "voice.failed": "音声を再生できません", "pet.talk": "話す", + "pet.menu": "デスクトップペットのメニュー", "quick.toCharacter": "{name}に話しかける…", "quick.history": "履歴", "quick.responding": "返信中…", diff --git a/src/index.html b/src/index.html index f13ab40..852f0a4 100644 --- a/src/index.html +++ b/src/index.html @@ -33,6 +33,7 @@ +