@caperjs/core 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/{CaptionsPlugin-Dc8fIrjy.js → CaptionsPlugin-DKhbmJvH.js} +15 -15
- package/lib/{CaptionsPlugin-Dc8fIrjy.js.map → CaptionsPlugin-DKhbmJvH.js.map} +1 -1
- package/lib/{DataAdapter-BY2114sp.js → DataAdapter-BZFTkFQ4.js} +4 -4
- package/lib/{DataAdapter-BY2114sp.js.map → DataAdapter-BZFTkFQ4.js.map} +1 -1
- package/lib/{DebugRenderer-BJMLILqI.js → DebugRenderer-C7X-nlXE.js} +2 -2
- package/lib/{DebugRenderer-BJMLILqI.js.map → DebugRenderer-C7X-nlXE.js.map} +1 -1
- package/lib/{DevToolsPlugin-wQ5rOkn0.js → DevToolsPlugin-P-atJ-5U.js} +2 -2
- package/lib/{DevToolsPlugin-wQ5rOkn0.js.map → DevToolsPlugin-P-atJ-5U.js.map} +1 -1
- package/lib/{GSAPPlugin-DHhSZKv8.js → GSAPPlugin-CeH9275z.js} +2 -2
- package/lib/{GSAPPlugin-DHhSZKv8.js.map → GSAPPlugin-CeH9275z.js.map} +1 -1
- package/lib/{LayoutPlugin-B-DF9SYM.js → LayoutPlugin-iZ3k6RsK.js} +4 -4
- package/lib/{LayoutPlugin-B-DF9SYM.js.map → LayoutPlugin-iZ3k6RsK.js.map} +1 -1
- package/lib/{SpinePlugin-Dz_3dljz.js → SpinePlugin-BWiavCpO.js} +2 -2
- package/lib/{SpinePlugin-Dz_3dljz.js.map → SpinePlugin-BWiavCpO.js.map} +1 -1
- package/lib/{StatsPlugin-Cg82JMBD.js → StatsPlugin-CBpzDJL0.js} +4 -4
- package/lib/{StatsPlugin-Cg82JMBD.js.map → StatsPlugin-CBpzDJL0.js.map} +1 -1
- package/lib/{VoiceOverPlugin-BR3ImT8C.js → VoiceOverPlugin-YaiKJtJ6.js} +26 -26
- package/lib/{VoiceOverPlugin-BR3ImT8C.js.map → VoiceOverPlugin-YaiKJtJ6.js.map} +1 -1
- package/lib/caper.mjs +95 -95
- package/lib/caper.mjs.map +1 -1
- package/lib/core/Application.d.ts +1 -1
- package/lib/core/Application.d.ts.map +1 -1
- package/lib/core/interfaces/IApplicationOptions.d.ts +2 -1
- package/lib/core/interfaces/IApplicationOptions.d.ts.map +1 -1
- package/lib/core/interfaces/ICoreSignals.d.ts +5 -1
- package/lib/core/interfaces/ICoreSignals.d.ts.map +1 -1
- package/lib/display/Container.d.ts +1 -1
- package/lib/display/Container.d.ts.map +1 -1
- package/lib/display/ParticleContainer.d.ts +1 -1
- package/lib/display/ParticleContainer.d.ts.map +1 -1
- package/lib/plugins/Plugin.d.ts +1 -1
- package/lib/plugins/Plugin.d.ts.map +1 -1
- package/lib/plugins/defaults.d.ts.map +1 -1
- package/lib/plugins/gesture/GesturePlugin.d.ts +58 -0
- package/lib/plugins/gesture/GesturePlugin.d.ts.map +1 -0
- package/lib/plugins/gesture/gestureMath.d.ts +32 -0
- package/lib/plugins/gesture/gestureMath.d.ts.map +1 -0
- package/lib/plugins/gesture/gestureMath.test.d.ts +2 -0
- package/lib/plugins/gesture/gestureMath.test.d.ts.map +1 -0
- package/lib/plugins/gesture/index.d.ts +3 -0
- package/lib/plugins/gesture/index.d.ts.map +1 -0
- package/lib/plugins/gesture/types.d.ts +45 -0
- package/lib/plugins/gesture/types.d.ts.map +1 -0
- package/lib/plugins/index.d.ts +1 -0
- package/lib/plugins/index.d.ts.map +1 -1
- package/lib/plugins/input/Controls.d.ts +5 -2
- package/lib/plugins/input/Controls.d.ts.map +1 -1
- package/lib/plugins/input/InputPlugin.d.ts +9 -2
- package/lib/plugins/input/InputPlugin.d.ts.map +1 -1
- package/lib/plugins/input/interfaces.d.ts +5 -3
- package/lib/plugins/input/interfaces.d.ts.map +1 -1
- package/lib/plugins/input/touch/{TouchControls.d.ts → VirtualControls.d.ts} +5 -4
- package/lib/plugins/input/touch/VirtualControls.d.ts.map +1 -0
- package/lib/plugins/input/touch/index.d.ts +1 -1
- package/lib/plugins/input/touch/index.d.ts.map +1 -1
- package/lib/{registries-CYCaYKZI.js → registries-qQmLeN0b.js} +505 -354
- package/lib/registries-qQmLeN0b.js.map +1 -0
- package/lib/utils/bind.test.d.ts +2 -0
- package/lib/utils/bind.test.d.ts.map +1 -0
- package/package.json +21 -20
- package/src/core/Application.ts +1 -1
- package/src/core/interfaces/IApplicationOptions.ts +2 -0
- package/src/core/interfaces/ICoreSignals.ts +9 -0
- package/src/display/Container.ts +1 -1
- package/src/display/ParticleContainer.ts +1 -1
- package/src/plugins/Plugin.ts +1 -1
- package/src/plugins/defaults.ts +6 -0
- package/src/plugins/gesture/GesturePlugin.ts +215 -0
- package/src/plugins/gesture/gestureMath.test.ts +75 -0
- package/src/plugins/gesture/gestureMath.ts +59 -0
- package/src/plugins/gesture/index.ts +2 -0
- package/src/plugins/gesture/types.ts +54 -0
- package/src/plugins/index.ts +1 -0
- package/src/plugins/input/Controls.ts +9 -3
- package/src/plugins/input/InputPlugin.ts +61 -14
- package/src/plugins/input/interfaces.ts +5 -3
- package/src/plugins/input/touch/{TouchControls.ts → VirtualControls.ts} +4 -1
- package/src/plugins/input/touch/index.ts +1 -1
- package/src/utils/bind.test.ts +99 -0
- package/src/version.ts +1 -1
- package/LICENSE +0 -22
- package/lib/plugins/input/touch/TouchControls.d.ts.map +0 -1
- package/lib/registries-CYCaYKZI.js.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { $ as e, Ft as t, Yt as n, ln as r, pn as i, ut as a } from "./registries-qQmLeN0b.js";
|
|
2
2
|
import { Assets as o, Container as s, Texture as c } from "pixi.js";
|
|
3
3
|
import { gsap as l } from "gsap";
|
|
4
4
|
//#region src/plugins/captions/CaptionsRenderer.ts
|
|
5
|
-
var u = class extends
|
|
5
|
+
var u = class extends a {
|
|
6
6
|
constructor(e) {
|
|
7
7
|
if (super({ autoResize: !1 }), this.plugin = e, this._size = {
|
|
8
8
|
width: 0,
|
|
@@ -71,7 +71,7 @@ var u = class extends n {
|
|
|
71
71
|
getSizeMultiplier() {
|
|
72
72
|
return this.plugin.options.fontSizeMultiplier;
|
|
73
73
|
}
|
|
74
|
-
}, d =
|
|
74
|
+
}, d = i, f = {
|
|
75
75
|
renderer: u,
|
|
76
76
|
defaultLocale: "en",
|
|
77
77
|
fontFile: "./caper/font/Sans.fnt",
|
|
@@ -95,7 +95,7 @@ var u = class extends n {
|
|
|
95
95
|
function p(e, t) {
|
|
96
96
|
return e <= 0 ? 0 : e > 0 && e <= 1 ? t * e : e;
|
|
97
97
|
}
|
|
98
|
-
var m = class extends
|
|
98
|
+
var m = class extends e {
|
|
99
99
|
constructor(...e) {
|
|
100
100
|
super(...e), this.id = "captions", this.view = new s(), this._dicts = {}, this._activeCaptionLine = -1, this._activeCaptionTime = 0, this._paused = !1;
|
|
101
101
|
}
|
|
@@ -105,11 +105,11 @@ var m = class extends t {
|
|
|
105
105
|
get options() {
|
|
106
106
|
return this._options;
|
|
107
107
|
}
|
|
108
|
-
set options(
|
|
108
|
+
set options(e) {
|
|
109
109
|
this._options = {
|
|
110
110
|
...this._options,
|
|
111
|
-
...
|
|
112
|
-
},
|
|
111
|
+
...e
|
|
112
|
+
}, e.padding && (this._options.padding = t(e.padding));
|
|
113
113
|
}
|
|
114
114
|
get activeCaptionId() {
|
|
115
115
|
return this._activeCaptionId;
|
|
@@ -150,8 +150,8 @@ var m = class extends t {
|
|
|
150
150
|
get padding() {
|
|
151
151
|
return this.options.padding;
|
|
152
152
|
}
|
|
153
|
-
set padding(
|
|
154
|
-
this.options.padding = e
|
|
153
|
+
set padding(e) {
|
|
154
|
+
this.options.padding = t(e), this.updateRenderer();
|
|
155
155
|
}
|
|
156
156
|
get distance() {
|
|
157
157
|
return this.options.distance;
|
|
@@ -177,11 +177,11 @@ var m = class extends t {
|
|
|
177
177
|
get debug() {
|
|
178
178
|
return d;
|
|
179
179
|
}
|
|
180
|
-
async initialize(
|
|
180
|
+
async initialize(e) {
|
|
181
181
|
if (this._options = {
|
|
182
182
|
...f,
|
|
183
|
-
...
|
|
184
|
-
}, this._originalOptions = { ...this._options },
|
|
183
|
+
...e
|
|
184
|
+
}, this._originalOptions = { ...this._options }, e?.padding && (this._options.padding = t(e.padding)), this._locale = this.app.i18n.locale, this._locales = this.app.i18n.locales, this._options.fontFile && await o.load(this._options.fontFile), this._options?.files?.length > 0) {
|
|
185
185
|
let e = this._options.files.filter((e) => this._locales.includes(e.id));
|
|
186
186
|
for (let t of e) await this.loadLocale(t.id);
|
|
187
187
|
}
|
|
@@ -202,10 +202,10 @@ var m = class extends t {
|
|
|
202
202
|
if (this._locale === "localeId") return;
|
|
203
203
|
let t = this._options.files.find((t) => e === t.id);
|
|
204
204
|
if (!t) {
|
|
205
|
-
|
|
205
|
+
r.error(`i18n:: Could not find locale file for ${e}`);
|
|
206
206
|
return;
|
|
207
207
|
}
|
|
208
|
-
this._dicts[e] = t.json ? await o.load(t.json) : await
|
|
208
|
+
this._dicts[e] = t.json ? await o.load(t.json) : await n(t);
|
|
209
209
|
}
|
|
210
210
|
render() {
|
|
211
211
|
this.renderer.resize();
|
|
@@ -274,4 +274,4 @@ var m = class extends t {
|
|
|
274
274
|
//#endregion
|
|
275
275
|
export { m as CaptionsPlugin };
|
|
276
276
|
|
|
277
|
-
//# sourceMappingURL=CaptionsPlugin-
|
|
277
|
+
//# sourceMappingURL=CaptionsPlugin-DKhbmJvH.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CaptionsPlugin-Dc8fIrjy.js","names":[],"sources":["../src/plugins/captions/CaptionsRenderer.ts","../src/plugins/captions/CaptionsPlugin.ts"],"sourcesContent":["import { gsap } from 'gsap';\nimport { BitmapText, Container as PIXIContainer, Sprite, Texture } from 'pixi.js';\nimport { Container } from '../../display';\nimport { type Size } from '../../utils';\nimport { CaptionsPlugin } from './CaptionsPlugin';\n\nexport type CaptionLine = {\n id: string;\n start: number;\n end: number;\n content: string;\n speaker?: string;\n};\n\nexport interface ICaptionRenderer extends PIXIContainer {\n visible: boolean;\n\n start(): void;\n\n stop(): void;\n\n lineBegin(line: CaptionLine): void;\n\n lineEnd(line: CaptionLine): void;\n\n resize(size?: Size): void;\n\n updateSettings(): void;\n\n destroy(): void;\n}\n\nexport class CaptionsRenderer extends Container implements ICaptionRenderer {\n private readonly _bg: Sprite;\n private readonly _text: BitmapText;\n private readonly _size: Size = { width: 0, height: 0 };\n private readonly fontSize = 48;\n\n constructor(private plugin: CaptionsPlugin) {\n super({ autoResize: false });\n\n this._bg = this.add.sprite({ asset: Texture.WHITE, anchor: [0.5, 0] });\n this._bg.tint = this.plugin.options.backgroundColor;\n this._bg.alpha = 0;\n\n this._text = this.add.bitmapText({\n font: plugin.options.fontName,\n resolution: 2,\n roundPixels: true,\n style: {\n fill: this.plugin.options.textColor,\n fontSize: this.fontSize * this.getSizeMultiplier(),\n fontWeight: 'bold',\n align: 'center',\n wordWrapWidth: this.plugin.maxWidth,\n wordWrap: true,\n lineHeight: this.fontSize * this.getSizeMultiplier() * 2 + 20,\n },\n });\n this._text.style.wordWrap = true;\n this._text.alpha = 0;\n this._text.visible = false;\n this._text.anchor.x = 0.5;\n this._text.anchor.y = 0;\n this.addChild(this._text);\n\n if (this.plugin.debug) {\n let isTapping = false;\n this._bg.eventMode = 'static';\n this._bg.on('pointertap', () => {\n if (isTapping) {\n return;\n }\n isTapping = true;\n setTimeout(() => {\n isTapping = false;\n void this.app.voiceover.stopVO();\n }, 100);\n });\n }\n }\n\n public start(): void {\n this._text.visible = true;\n this._bg.visible = true;\n\n gsap.killTweensOf([this._bg, this._text]);\n this.animate({ alpha: this.plugin.options.backgroundAlpha, visible: true, duration: 0.2 }, this._bg);\n this.animate({ alpha: 1, visible: true, duration: 0.2 }, this._text);\n }\n\n public stop(): void {\n gsap.killTweensOf([this._bg, this._text]);\n this.animate({ alpha: 0, visible: false, duration: 0.2 }, [this._bg, this._text]);\n }\n\n public lineBegin(line: CaptionLine): void {\n let text = line.content\n .replace(/<[^>]*>/gi, '') // remove html tags\n .replace(/\\[.*]\\W*/gi, ''); // remove brackets\n if (line.start === 0) {\n text = text.charAt(0).toUpperCase() + text.slice(1);\n }\n this._text.text = text;\n this.resize();\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n public lineEnd(_line: CaptionLine): void {}\n\n public resize(): void {\n const size = this.app.size;\n const opts = this.plugin.options;\n\n this._size.width = size.width;\n this._size.height = size.height;\n\n this._text.style.fontSize = this.fontSize * this.getSizeMultiplier();\n this._text.style.wordWrapWidth = opts.maxWidth * 2;\n this._text.scale.set(0.5);\n this._text.position.set(this._size.width * 0.5, 0);\n\n this._bg.position.set(this._size.width * 0.5, 0);\n\n let h = this._text.height;\n if (opts.padding.top) {\n h += opts.padding.top;\n }\n if (opts.padding.bottom) {\n h += opts.padding.bottom;\n }\n this._bg.height = h;\n\n this._text.y += opts.padding.top;\n\n if (opts.floating) {\n let w = this._text.width;\n\n if (opts.padding.left) {\n w += opts.padding.left;\n }\n if (opts.padding.right) {\n w += opts.padding.right;\n }\n\n this._bg.x += opts.padding.right * 0.5 - opts.padding.left * 0.5;\n this._bg.width = w;\n } else {\n this._bg.width = size.width;\n }\n\n if (opts.position === 'top') {\n this.position.set(-size.width * 0.5, Math.round(-size.height * 0.5));\n if (opts.floating) {\n this.position.y += Math.round(opts.distance - this._bg.y);\n }\n } else {\n this.position.set(-size.width * 0.5, Math.round(size.height * 0.5 - this._bg.height));\n if (opts.floating) {\n this.position.y -= Math.round(opts.distance + this._bg.y);\n }\n }\n }\n\n updateSettings() {\n if (this.plugin.options.enabled) {\n this._text.style.fill = this.plugin.options.textColor;\n this._bg.tint = this.plugin.options.backgroundColor;\n if (this._bg.visible) {\n this._bg.alpha = this.plugin.options.backgroundAlpha;\n this.resize();\n }\n } else {\n this.stop();\n this._bg.visible = false;\n this._text.visible = false;\n this._bg.alpha = this._text.alpha = 0;\n }\n }\n\n private getSizeMultiplier(): number {\n return this.plugin.options.fontSizeMultiplier;\n }\n}\n","import { Assets, Container, Ticker } from 'pixi.js';\nimport type { ImportListItem, ImportListItemModule, Padding, PointLike } from '../../utils';\nimport { ensurePadding, getDynamicModuleFromImportListItem, isDev, Logger } from '../../utils';\nimport type { IAudioInstance } from '../audio';\nimport type { IPlugin } from '../Plugin';\nimport { Plugin } from '../Plugin';\nimport type { ICaptionRenderer } from './CaptionsRenderer';\nimport { CaptionsRenderer } from './CaptionsRenderer';\n\nconst isDebug = isDev;\n\n/**\n * Type definition for i18n dictionary.\n */\ntype CaptionsDict = Record<string, any>;\n\n/**\n * Type definition for i18n import list item.\n */\ntype CaptionsImportListItem<T> = {\n id: string;\n namedExport?: string;\n options?: any;\n module?: ImportListItemModule<T>;\n} & {\n json?: string;\n};\n\ntype CaptionRendererConstructor = new (owner: CaptionsPlugin) => ICaptionRenderer;\n\n/**\n * Type definition for i18n options.\n */\nexport type CaptionsOptions = {\n renderer: CaptionRendererConstructor;\n defaultLocale: string;\n files: CaptionsImportListItem<CaptionsDict>[];\n fontFile: string;\n fontName: string;\n fontSizeMultiplier: number;\n maxWidth: number;\n textColor: number;\n backgroundColor: number;\n backgroundAlpha: number;\n enabled: boolean;\n floating: boolean;\n distance: number;\n padding: Padding;\n position: 'top' | 'bottom';\n};\n\n/**\n * Default options for i18n module.\n */\nconst defaultOptions: Partial<CaptionsOptions> = {\n renderer: CaptionsRenderer,\n defaultLocale: 'en',\n fontFile: './caper/font/Sans.fnt',\n fontName: 'Sans',\n fontSizeMultiplier: 1,\n maxWidth: 0.8,\n textColor: 0xffffff,\n backgroundColor: 0x0,\n backgroundAlpha: 0.4,\n enabled: true,\n floating: false,\n distance: 0,\n padding: { top: 20, left: 0, bottom: 20, right: 0 },\n position: 'top',\n};\n\nfunction resolveMaxWidth(value: number, appWidth: number) {\n if (value <= 0) {\n return 0;\n }\n if (value > 0 && value <= 1) {\n return appWidth * value;\n }\n return value;\n}\n\n/**\n * Interface for i18n module.\n */\nexport interface ICaptionsPlugin extends IPlugin {\n readonly locale: string;\n view: Container;\n enabled: boolean;\n floating: boolean;\n distance: number;\n padding: Padding;\n position: 'top' | 'bottom';\n backgroundColor: number;\n textColor: number;\n backgroundAlpha: number;\n fontSizeMultiplier: number;\n maxWidth: number;\n options: Partial<CaptionsOptions>;\n\n setLocale(localeId: string): Promise<string>;\n\n loadLocale(localeId: string): Promise<void>;\n\n render(): void;\n}\n\n/**\n * i18n module class.\n */\nexport class CaptionsPlugin extends Plugin<CaptionsOptions> implements ICaptionsPlugin {\n public readonly id = 'captions';\n public view: Container = new Container();\n public renderer: ICaptionRenderer;\n private _dicts: Record<string, CaptionsDict> = {};\n private _locales: string[];\n private _activeCaptionLine = -1;\n private _activeCaptionTime = 0;\n\n private _locale: string;\n\n /**\n * Getter for locale.\n */\n get locale(): string {\n return this._locale;\n }\n\n private _originalOptions: CaptionsOptions;\n\n get options(): CaptionsOptions {\n return this._options;\n }\n\n set options(value: Partial<CaptionsOptions>) {\n this._options = { ...this._options, ...value };\n\n if (value.padding) {\n this._options.padding = ensurePadding(value.padding);\n }\n }\n\n private _activeCaptionId?: string;\n\n get activeCaptionId() {\n return this._activeCaptionId;\n }\n\n private _paused: boolean = false;\n\n get paused(): boolean {\n return this._paused;\n }\n\n set paused(value: boolean) {\n this._paused = value;\n }\n\n get floating(): boolean {\n return this.options.floating;\n }\n\n set floating(value: boolean) {\n this.options.floating = value;\n this.updateRenderer();\n }\n\n public get enabled(): boolean {\n return this.options.enabled;\n }\n\n set enabled(value: boolean) {\n this.options.enabled = value;\n if (this.enabled) {\n this.view.visible = true;\n } else {\n this.view.visible = false;\n }\n }\n\n public get position(): 'top' | 'bottom' {\n return this.options.position;\n }\n\n public set position(value: 'top' | 'bottom') {\n this.options.position = value;\n this.renderer.updateSettings();\n }\n\n set backgroundColor(value: number) {\n this.options.backgroundColor = value;\n this.updateRenderer();\n }\n\n set textColor(value: number) {\n this.options.textColor = value;\n this.updateRenderer();\n }\n\n set backgroundAlpha(value: number) {\n this.options.backgroundAlpha = value;\n this.updateRenderer();\n }\n\n get padding(): Padding {\n return this.options.padding;\n }\n\n set padding(value: Partial<Padding> | PointLike) {\n this.options.padding = ensurePadding(value);\n this.updateRenderer();\n }\n\n get distance(): number {\n return this.options.distance;\n }\n\n set distance(value: number) {\n this.options.distance = value;\n this.updateRenderer();\n }\n\n public get fontSizeMultiplier(): number {\n return this.options.fontSizeMultiplier;\n }\n\n public set fontSizeMultiplier(value: number) {\n this.options.fontSizeMultiplier = value;\n this.renderer.resize();\n }\n\n public get maxWidth(): number {\n return this.options.maxWidth;\n }\n\n public set maxWidth(value: number) {\n this.options.maxWidth = resolveMaxWidth(value, this.app.size.width);\n this.renderer?.resize();\n }\n\n get list(): CaptionsDict {\n return this._dicts[this._locale];\n }\n\n get debug(): boolean {\n return isDebug;\n }\n\n /**\n * Initializes the i18n module.\n * sets the default locale and loads the locale files.\n * @param _app\n * @param options The i18n options.\n * @returns Promise<void>\n */\n public async initialize(options: Partial<CaptionsOptions>): Promise<void> {\n this._options = {\n ...defaultOptions,\n ...options,\n } as CaptionsOptions;\n\n this._originalOptions = { ...this._options };\n\n if (options?.padding) {\n this._options.padding = ensurePadding(options.padding);\n }\n\n this._locale = this.app.i18n.locale;\n this._locales = this.app.i18n.locales;\n\n if (this._options.fontFile) {\n await Assets.load(this._options.fontFile);\n }\n\n if (this._options?.files?.length > 0) {\n const files = this._options.files.filter((file) => this._locales.includes(file.id));\n for (const file of files) {\n await this.loadLocale(file.id);\n }\n }\n\n this.addSignalConnection(this.app.onResize.connect(this.handleResize, 'highest'));\n }\n\n private handleResize() {\n this.maxWidth = this._originalOptions.maxWidth;\n }\n\n public postInitialize(): void {\n this.app.i18n.onLocaleChanged.connect(this._handleLocaleChange);\n this.app.voiceover.onVoiceOverStart.connect(this._handleVoiceOverStart);\n this.app.voiceover.onVoiceOverPaused.connect(this._handleVoiceOverPaused);\n this.app.voiceover.onVoiceOverResumed.connect(this._handleVoiceOverResumed);\n this.app.voiceover.onVoiceOverComplete.connect(this._handleVoiceoverComplete);\n this.app.voiceover.onVoiceOverStopped.connect(this._handleVoiceoverStopped);\n\n this.app.stage.addChild(this.view);\n this._options.maxWidth = resolveMaxWidth(this._originalOptions.maxWidth, this.app.size.width);\n const RendererClass: CaptionRendererConstructor = this.options.renderer;\n this.renderer = this.view.addChild(new RendererClass(this)) as CaptionsRenderer;\n\n this.app.ticker.add(this.update);\n this.app.scenes.onSceneChangeStart.connect(this.stopAllCaptions);\n }\n\n /**\n * Sets the locale.\n * If the locale is not loaded, it will load it first.\n * @param localeId The locale id to set.\n * @returns Promise<string>\n */\n async setLocale(localeId: string) {\n if (this._locale === localeId) {\n return this._locale;\n }\n if (this._activeCaptionId) {\n this.stopCaption(this._activeCaptionId);\n }\n this._activeCaptionId = undefined;\n await this._loadAndSetLocale(localeId);\n this._locale = localeId;\n return this._locale;\n }\n\n /**\n * Loads a locale.\n * @param localeId The locale id to load.\n * @returns Promise<void>\n */\n async loadLocale(localeId: string) {\n if (this._locale === 'localeId') {\n return;\n }\n const file = this._options.files.find((file) => localeId === file.id);\n if (!file) {\n Logger.error(`i18n:: Could not find locale file for ${localeId}`);\n return;\n }\n this._dicts[localeId] = file.json\n ? await Assets.load(file.json)\n : await getDynamicModuleFromImportListItem(file as ImportListItem<CaptionsDict>);\n }\n\n render() {\n this.renderer.resize();\n }\n\n update(ticker: Ticker): void {\n if (this._paused) {\n return;\n }\n const dt: number = ticker.deltaMS / 1000;\n const id = this._activeCaptionId;\n if (id) {\n this._activeCaptionTime += dt;\n const ms = this._activeCaptionTime * 1000;\n const cc = this.list[id];\n const n = cc.length;\n for (let i = 0; i < n; i++) {\n if (ms >= cc[i].start && ms < cc[i].end) {\n if (this._activeCaptionLine !== i) {\n this.playLine(id, i);\n }\n break;\n }\n }\n if (ms >= cc[n - 1].end) {\n this.playLine(id, -1);\n }\n }\n }\n\n public playCaption(id: string): void {\n // remove extension from id\n id = this._getId(id);\n this.playLine(id, 0);\n }\n\n public stopCaption(id: string): void {\n // remove extension from id\n id = this._getId(id);\n if (this._activeCaptionId === id) {\n this.playLine(id, -1);\n }\n }\n\n public stopAllCaptions(): void {\n this.renderer?.stop();\n this._activeCaptionId = undefined;\n this._activeCaptionLine = -1;\n }\n\n private _getId(id: string) {\n return id.replace(/\\.[^/.]+$/, '');\n }\n\n private updateRenderer() {\n if (!this.enabled) {\n return;\n }\n this.renderer.updateSettings();\n }\n\n private _handleLocaleChange() {\n void this.setLocale(this.app.i18n.locale);\n }\n\n private _handleVoiceOverStart(vo: IAudioInstance) {\n this.playCaption(vo.id);\n }\n\n private _handleVoiceOverPaused() {\n this.paused = true;\n }\n\n private _handleVoiceOverResumed() {\n this.paused = false;\n }\n\n private _handleVoiceoverComplete(vo: IAudioInstance) {\n const id = this._getId(vo?.id || '');\n if (this._activeCaptionId === id) {\n this.stopCaption(id);\n }\n }\n\n private _handleVoiceoverStopped() {\n this.stopAllCaptions();\n }\n\n /**\n * Loads and sets a locale.\n * If the locale is not loaded, it will load it first.\n * @param localeId The locale id to load and set.\n */\n private async _loadAndSetLocale(localeId: string) {\n if (!this._dicts[localeId]) {\n await this.loadLocale(localeId);\n }\n }\n\n private playLine(id: string, index: number) {\n const cc = this.list[id];\n const line = cc ? cc[index] : undefined;\n if (line) {\n if (this._activeCaptionId !== id) {\n this._activeCaptionId = id;\n this._activeCaptionTime = 0;\n this._activeCaptionLine = -1;\n this.renderer?.start();\n }\n if (this._activeCaptionLine !== index) {\n this._activeCaptionLine = index;\n this.renderer?.lineBegin({\n id: this._activeCaptionId,\n ...cc[index],\n });\n }\n } else if (this._activeCaptionId === id && cc) {\n this.renderer?.lineEnd({\n id: this._activeCaptionId,\n ...cc[this._activeCaptionLine],\n });\n this.renderer?.stop();\n this._activeCaptionId = undefined;\n this._activeCaptionLine = -1;\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CaptionsPlugin-DKhbmJvH.js","names":[],"sources":["../src/plugins/captions/CaptionsRenderer.ts","../src/plugins/captions/CaptionsPlugin.ts"],"sourcesContent":["import { gsap } from 'gsap';\nimport { BitmapText, Container as PIXIContainer, Sprite, Texture } from 'pixi.js';\nimport { Container } from '../../display';\nimport { type Size } from '../../utils';\nimport { CaptionsPlugin } from './CaptionsPlugin';\n\nexport type CaptionLine = {\n id: string;\n start: number;\n end: number;\n content: string;\n speaker?: string;\n};\n\nexport interface ICaptionRenderer extends PIXIContainer {\n visible: boolean;\n\n start(): void;\n\n stop(): void;\n\n lineBegin(line: CaptionLine): void;\n\n lineEnd(line: CaptionLine): void;\n\n resize(size?: Size): void;\n\n updateSettings(): void;\n\n destroy(): void;\n}\n\nexport class CaptionsRenderer extends Container implements ICaptionRenderer {\n private readonly _bg: Sprite;\n private readonly _text: BitmapText;\n private readonly _size: Size = { width: 0, height: 0 };\n private readonly fontSize = 48;\n\n constructor(private plugin: CaptionsPlugin) {\n super({ autoResize: false });\n\n this._bg = this.add.sprite({ asset: Texture.WHITE, anchor: [0.5, 0] });\n this._bg.tint = this.plugin.options.backgroundColor;\n this._bg.alpha = 0;\n\n this._text = this.add.bitmapText({\n font: plugin.options.fontName,\n resolution: 2,\n roundPixels: true,\n style: {\n fill: this.plugin.options.textColor,\n fontSize: this.fontSize * this.getSizeMultiplier(),\n fontWeight: 'bold',\n align: 'center',\n wordWrapWidth: this.plugin.maxWidth,\n wordWrap: true,\n lineHeight: this.fontSize * this.getSizeMultiplier() * 2 + 20,\n },\n });\n this._text.style.wordWrap = true;\n this._text.alpha = 0;\n this._text.visible = false;\n this._text.anchor.x = 0.5;\n this._text.anchor.y = 0;\n this.addChild(this._text);\n\n if (this.plugin.debug) {\n let isTapping = false;\n this._bg.eventMode = 'static';\n this._bg.on('pointertap', () => {\n if (isTapping) {\n return;\n }\n isTapping = true;\n setTimeout(() => {\n isTapping = false;\n void this.app.voiceover.stopVO();\n }, 100);\n });\n }\n }\n\n public start(): void {\n this._text.visible = true;\n this._bg.visible = true;\n\n gsap.killTweensOf([this._bg, this._text]);\n this.animate({ alpha: this.plugin.options.backgroundAlpha, visible: true, duration: 0.2 }, this._bg);\n this.animate({ alpha: 1, visible: true, duration: 0.2 }, this._text);\n }\n\n public stop(): void {\n gsap.killTweensOf([this._bg, this._text]);\n this.animate({ alpha: 0, visible: false, duration: 0.2 }, [this._bg, this._text]);\n }\n\n public lineBegin(line: CaptionLine): void {\n let text = line.content\n .replace(/<[^>]*>/gi, '') // remove html tags\n .replace(/\\[.*]\\W*/gi, ''); // remove brackets\n if (line.start === 0) {\n text = text.charAt(0).toUpperCase() + text.slice(1);\n }\n this._text.text = text;\n this.resize();\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n public lineEnd(_line: CaptionLine): void {}\n\n public resize(): void {\n const size = this.app.size;\n const opts = this.plugin.options;\n\n this._size.width = size.width;\n this._size.height = size.height;\n\n this._text.style.fontSize = this.fontSize * this.getSizeMultiplier();\n this._text.style.wordWrapWidth = opts.maxWidth * 2;\n this._text.scale.set(0.5);\n this._text.position.set(this._size.width * 0.5, 0);\n\n this._bg.position.set(this._size.width * 0.5, 0);\n\n let h = this._text.height;\n if (opts.padding.top) {\n h += opts.padding.top;\n }\n if (opts.padding.bottom) {\n h += opts.padding.bottom;\n }\n this._bg.height = h;\n\n this._text.y += opts.padding.top;\n\n if (opts.floating) {\n let w = this._text.width;\n\n if (opts.padding.left) {\n w += opts.padding.left;\n }\n if (opts.padding.right) {\n w += opts.padding.right;\n }\n\n this._bg.x += opts.padding.right * 0.5 - opts.padding.left * 0.5;\n this._bg.width = w;\n } else {\n this._bg.width = size.width;\n }\n\n if (opts.position === 'top') {\n this.position.set(-size.width * 0.5, Math.round(-size.height * 0.5));\n if (opts.floating) {\n this.position.y += Math.round(opts.distance - this._bg.y);\n }\n } else {\n this.position.set(-size.width * 0.5, Math.round(size.height * 0.5 - this._bg.height));\n if (opts.floating) {\n this.position.y -= Math.round(opts.distance + this._bg.y);\n }\n }\n }\n\n updateSettings() {\n if (this.plugin.options.enabled) {\n this._text.style.fill = this.plugin.options.textColor;\n this._bg.tint = this.plugin.options.backgroundColor;\n if (this._bg.visible) {\n this._bg.alpha = this.plugin.options.backgroundAlpha;\n this.resize();\n }\n } else {\n this.stop();\n this._bg.visible = false;\n this._text.visible = false;\n this._bg.alpha = this._text.alpha = 0;\n }\n }\n\n private getSizeMultiplier(): number {\n return this.plugin.options.fontSizeMultiplier;\n }\n}\n","import { Assets, Container, Ticker } from 'pixi.js';\nimport type { ImportListItem, ImportListItemModule, Padding, PointLike } from '../../utils';\nimport { ensurePadding, getDynamicModuleFromImportListItem, isDev, Logger } from '../../utils';\nimport type { IAudioInstance } from '../audio';\nimport type { IPlugin } from '../Plugin';\nimport { Plugin } from '../Plugin';\nimport type { ICaptionRenderer } from './CaptionsRenderer';\nimport { CaptionsRenderer } from './CaptionsRenderer';\n\nconst isDebug = isDev;\n\n/**\n * Type definition for i18n dictionary.\n */\ntype CaptionsDict = Record<string, any>;\n\n/**\n * Type definition for i18n import list item.\n */\ntype CaptionsImportListItem<T> = {\n id: string;\n namedExport?: string;\n options?: any;\n module?: ImportListItemModule<T>;\n} & {\n json?: string;\n};\n\ntype CaptionRendererConstructor = new (owner: CaptionsPlugin) => ICaptionRenderer;\n\n/**\n * Type definition for i18n options.\n */\nexport type CaptionsOptions = {\n renderer: CaptionRendererConstructor;\n defaultLocale: string;\n files: CaptionsImportListItem<CaptionsDict>[];\n fontFile: string;\n fontName: string;\n fontSizeMultiplier: number;\n maxWidth: number;\n textColor: number;\n backgroundColor: number;\n backgroundAlpha: number;\n enabled: boolean;\n floating: boolean;\n distance: number;\n padding: Padding;\n position: 'top' | 'bottom';\n};\n\n/**\n * Default options for i18n module.\n */\nconst defaultOptions: Partial<CaptionsOptions> = {\n renderer: CaptionsRenderer,\n defaultLocale: 'en',\n fontFile: './caper/font/Sans.fnt',\n fontName: 'Sans',\n fontSizeMultiplier: 1,\n maxWidth: 0.8,\n textColor: 0xffffff,\n backgroundColor: 0x0,\n backgroundAlpha: 0.4,\n enabled: true,\n floating: false,\n distance: 0,\n padding: { top: 20, left: 0, bottom: 20, right: 0 },\n position: 'top',\n};\n\nfunction resolveMaxWidth(value: number, appWidth: number) {\n if (value <= 0) {\n return 0;\n }\n if (value > 0 && value <= 1) {\n return appWidth * value;\n }\n return value;\n}\n\n/**\n * Interface for i18n module.\n */\nexport interface ICaptionsPlugin extends IPlugin {\n readonly locale: string;\n view: Container;\n enabled: boolean;\n floating: boolean;\n distance: number;\n padding: Padding;\n position: 'top' | 'bottom';\n backgroundColor: number;\n textColor: number;\n backgroundAlpha: number;\n fontSizeMultiplier: number;\n maxWidth: number;\n options: Partial<CaptionsOptions>;\n\n setLocale(localeId: string): Promise<string>;\n\n loadLocale(localeId: string): Promise<void>;\n\n render(): void;\n}\n\n/**\n * i18n module class.\n */\nexport class CaptionsPlugin extends Plugin<CaptionsOptions> implements ICaptionsPlugin {\n public readonly id = 'captions';\n public view: Container = new Container();\n public renderer: ICaptionRenderer;\n private _dicts: Record<string, CaptionsDict> = {};\n private _locales: string[];\n private _activeCaptionLine = -1;\n private _activeCaptionTime = 0;\n\n private _locale: string;\n\n /**\n * Getter for locale.\n */\n get locale(): string {\n return this._locale;\n }\n\n private _originalOptions: CaptionsOptions;\n\n get options(): CaptionsOptions {\n return this._options;\n }\n\n set options(value: Partial<CaptionsOptions>) {\n this._options = { ...this._options, ...value };\n\n if (value.padding) {\n this._options.padding = ensurePadding(value.padding);\n }\n }\n\n private _activeCaptionId?: string;\n\n get activeCaptionId() {\n return this._activeCaptionId;\n }\n\n private _paused: boolean = false;\n\n get paused(): boolean {\n return this._paused;\n }\n\n set paused(value: boolean) {\n this._paused = value;\n }\n\n get floating(): boolean {\n return this.options.floating;\n }\n\n set floating(value: boolean) {\n this.options.floating = value;\n this.updateRenderer();\n }\n\n public get enabled(): boolean {\n return this.options.enabled;\n }\n\n set enabled(value: boolean) {\n this.options.enabled = value;\n if (this.enabled) {\n this.view.visible = true;\n } else {\n this.view.visible = false;\n }\n }\n\n public get position(): 'top' | 'bottom' {\n return this.options.position;\n }\n\n public set position(value: 'top' | 'bottom') {\n this.options.position = value;\n this.renderer.updateSettings();\n }\n\n set backgroundColor(value: number) {\n this.options.backgroundColor = value;\n this.updateRenderer();\n }\n\n set textColor(value: number) {\n this.options.textColor = value;\n this.updateRenderer();\n }\n\n set backgroundAlpha(value: number) {\n this.options.backgroundAlpha = value;\n this.updateRenderer();\n }\n\n get padding(): Padding {\n return this.options.padding;\n }\n\n set padding(value: Partial<Padding> | PointLike) {\n this.options.padding = ensurePadding(value);\n this.updateRenderer();\n }\n\n get distance(): number {\n return this.options.distance;\n }\n\n set distance(value: number) {\n this.options.distance = value;\n this.updateRenderer();\n }\n\n public get fontSizeMultiplier(): number {\n return this.options.fontSizeMultiplier;\n }\n\n public set fontSizeMultiplier(value: number) {\n this.options.fontSizeMultiplier = value;\n this.renderer.resize();\n }\n\n public get maxWidth(): number {\n return this.options.maxWidth;\n }\n\n public set maxWidth(value: number) {\n this.options.maxWidth = resolveMaxWidth(value, this.app.size.width);\n this.renderer?.resize();\n }\n\n get list(): CaptionsDict {\n return this._dicts[this._locale];\n }\n\n get debug(): boolean {\n return isDebug;\n }\n\n /**\n * Initializes the i18n module.\n * sets the default locale and loads the locale files.\n * @param _app\n * @param options The i18n options.\n * @returns Promise<void>\n */\n public async initialize(options: Partial<CaptionsOptions>): Promise<void> {\n this._options = {\n ...defaultOptions,\n ...options,\n } as CaptionsOptions;\n\n this._originalOptions = { ...this._options };\n\n if (options?.padding) {\n this._options.padding = ensurePadding(options.padding);\n }\n\n this._locale = this.app.i18n.locale;\n this._locales = this.app.i18n.locales;\n\n if (this._options.fontFile) {\n await Assets.load(this._options.fontFile);\n }\n\n if (this._options?.files?.length > 0) {\n const files = this._options.files.filter((file) => this._locales.includes(file.id));\n for (const file of files) {\n await this.loadLocale(file.id);\n }\n }\n\n this.addSignalConnection(this.app.onResize.connect(this.handleResize, 'highest'));\n }\n\n private handleResize() {\n this.maxWidth = this._originalOptions.maxWidth;\n }\n\n public postInitialize(): void {\n this.app.i18n.onLocaleChanged.connect(this._handleLocaleChange);\n this.app.voiceover.onVoiceOverStart.connect(this._handleVoiceOverStart);\n this.app.voiceover.onVoiceOverPaused.connect(this._handleVoiceOverPaused);\n this.app.voiceover.onVoiceOverResumed.connect(this._handleVoiceOverResumed);\n this.app.voiceover.onVoiceOverComplete.connect(this._handleVoiceoverComplete);\n this.app.voiceover.onVoiceOverStopped.connect(this._handleVoiceoverStopped);\n\n this.app.stage.addChild(this.view);\n this._options.maxWidth = resolveMaxWidth(this._originalOptions.maxWidth, this.app.size.width);\n const RendererClass: CaptionRendererConstructor = this.options.renderer;\n this.renderer = this.view.addChild(new RendererClass(this)) as CaptionsRenderer;\n\n this.app.ticker.add(this.update);\n this.app.scenes.onSceneChangeStart.connect(this.stopAllCaptions);\n }\n\n /**\n * Sets the locale.\n * If the locale is not loaded, it will load it first.\n * @param localeId The locale id to set.\n * @returns Promise<string>\n */\n async setLocale(localeId: string) {\n if (this._locale === localeId) {\n return this._locale;\n }\n if (this._activeCaptionId) {\n this.stopCaption(this._activeCaptionId);\n }\n this._activeCaptionId = undefined;\n await this._loadAndSetLocale(localeId);\n this._locale = localeId;\n return this._locale;\n }\n\n /**\n * Loads a locale.\n * @param localeId The locale id to load.\n * @returns Promise<void>\n */\n async loadLocale(localeId: string) {\n if (this._locale === 'localeId') {\n return;\n }\n const file = this._options.files.find((file) => localeId === file.id);\n if (!file) {\n Logger.error(`i18n:: Could not find locale file for ${localeId}`);\n return;\n }\n this._dicts[localeId] = file.json\n ? await Assets.load(file.json)\n : await getDynamicModuleFromImportListItem(file as ImportListItem<CaptionsDict>);\n }\n\n render() {\n this.renderer.resize();\n }\n\n update(ticker: Ticker): void {\n if (this._paused) {\n return;\n }\n const dt: number = ticker.deltaMS / 1000;\n const id = this._activeCaptionId;\n if (id) {\n this._activeCaptionTime += dt;\n const ms = this._activeCaptionTime * 1000;\n const cc = this.list[id];\n const n = cc.length;\n for (let i = 0; i < n; i++) {\n if (ms >= cc[i].start && ms < cc[i].end) {\n if (this._activeCaptionLine !== i) {\n this.playLine(id, i);\n }\n break;\n }\n }\n if (ms >= cc[n - 1].end) {\n this.playLine(id, -1);\n }\n }\n }\n\n public playCaption(id: string): void {\n // remove extension from id\n id = this._getId(id);\n this.playLine(id, 0);\n }\n\n public stopCaption(id: string): void {\n // remove extension from id\n id = this._getId(id);\n if (this._activeCaptionId === id) {\n this.playLine(id, -1);\n }\n }\n\n public stopAllCaptions(): void {\n this.renderer?.stop();\n this._activeCaptionId = undefined;\n this._activeCaptionLine = -1;\n }\n\n private _getId(id: string) {\n return id.replace(/\\.[^/.]+$/, '');\n }\n\n private updateRenderer() {\n if (!this.enabled) {\n return;\n }\n this.renderer.updateSettings();\n }\n\n private _handleLocaleChange() {\n void this.setLocale(this.app.i18n.locale);\n }\n\n private _handleVoiceOverStart(vo: IAudioInstance) {\n this.playCaption(vo.id);\n }\n\n private _handleVoiceOverPaused() {\n this.paused = true;\n }\n\n private _handleVoiceOverResumed() {\n this.paused = false;\n }\n\n private _handleVoiceoverComplete(vo: IAudioInstance) {\n const id = this._getId(vo?.id || '');\n if (this._activeCaptionId === id) {\n this.stopCaption(id);\n }\n }\n\n private _handleVoiceoverStopped() {\n this.stopAllCaptions();\n }\n\n /**\n * Loads and sets a locale.\n * If the locale is not loaded, it will load it first.\n * @param localeId The locale id to load and set.\n */\n private async _loadAndSetLocale(localeId: string) {\n if (!this._dicts[localeId]) {\n await this.loadLocale(localeId);\n }\n }\n\n private playLine(id: string, index: number) {\n const cc = this.list[id];\n const line = cc ? cc[index] : undefined;\n if (line) {\n if (this._activeCaptionId !== id) {\n this._activeCaptionId = id;\n this._activeCaptionTime = 0;\n this._activeCaptionLine = -1;\n this.renderer?.start();\n }\n if (this._activeCaptionLine !== index) {\n this._activeCaptionLine = index;\n this.renderer?.lineBegin({\n id: this._activeCaptionId,\n ...cc[index],\n });\n }\n } else if (this._activeCaptionId === id && cc) {\n this.renderer?.lineEnd({\n id: this._activeCaptionId,\n ...cc[this._activeCaptionLine],\n });\n this.renderer?.stop();\n this._activeCaptionId = undefined;\n this._activeCaptionLine = -1;\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { $ as e, Lt as t, Tn as n, vt as r } from "./registries-qQmLeN0b.js";
|
|
2
2
|
//#region src/plugins/DataAdapter.ts
|
|
3
|
-
var i = /* @__PURE__ */
|
|
3
|
+
var i = /* @__PURE__ */ n({
|
|
4
4
|
DataAdapter: () => o,
|
|
5
5
|
defineData: () => a
|
|
6
6
|
});
|
|
7
7
|
function a(e) {
|
|
8
8
|
return e;
|
|
9
9
|
}
|
|
10
|
-
var o = class extends
|
|
10
|
+
var o = class extends e {
|
|
11
11
|
constructor(e = "data") {
|
|
12
12
|
super(e), this.onDataChange = new r(), this.backupKeys = [], this.backupAll = !1, this.namespace = "", this.overrideWithLocalStorage = !0;
|
|
13
13
|
}
|
|
@@ -81,4 +81,4 @@ var o = class extends n {
|
|
|
81
81
|
//#endregion
|
|
82
82
|
export { i as n, a as r, o as t };
|
|
83
83
|
|
|
84
|
-
//# sourceMappingURL=DataAdapter-
|
|
84
|
+
//# sourceMappingURL=DataAdapter-BZFTkFQ4.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataAdapter-BY2114sp.js","names":[],"sources":["../src/plugins/DataAdapter.ts"],"sourcesContent":["import { Signal } from '../signals';\nimport { AppTypeOverrides, deepMerge, DeepPartial } from '../utils';\nimport { Plugin } from './Plugin';\n\nexport type DataSchema = {\n [key: string]: any;\n};\n\n/**\n * Interface for the options of the DataAdapter.\n */\nexport interface IDataAdapterOptions {\n initial: Partial<AppTypeOverrides['Data']>;\n /**\n * The namespace to use for the keys in local storage.\n */\n namespace: string;\n /**\n * Whether to override the data with the data from local storage.\n */\n overrideWithLocalStorage: boolean;\n /**\n * Whether to backup all data to local storage.\n */\n backupAll: boolean;\n /**\n * The keys to backup to local storage.\n */\n backupKeys: Array<keyof AppTypeOverrides['Data']>;\n}\n\nexport interface DataChangeSignalDetail {\n key?: any;\n value?: any;\n restore?: boolean;\n clear?: boolean;\n}\n\ntype DataAdapterType = AppTypeOverrides['Data'];\n\nexport interface IDataAdapter {\n get(): DataAdapterType;\n get<K extends keyof DataAdapterType>(key: K): DataAdapterType[K] | undefined;\n set<K extends keyof DataAdapterType>(key: K, data: DataAdapterType[K]): DataAdapterType;\n set(data: DeepPartial<DataAdapterType>, merge?: boolean): DataAdapterType;\n clear(): void;\n clear<K extends keyof DataAdapterType>(key: K): void;\n increment<\n K extends keyof DataAdapterType &\n { [P in keyof DataAdapterType]: DataAdapterType[P] extends number ? P : never }[keyof DataAdapterType],\n >(\n key: K,\n amount?: number,\n ): DataAdapterType[K];\n concat<\n K extends keyof DataAdapterType &\n { [P in keyof DataAdapterType]: DataAdapterType[P] extends any[] ? P : never }[keyof DataAdapterType],\n >(\n key: K,\n value: DataAdapterType[K] extends (infer E)[] ? E | E[] : never,\n ): DataAdapterType[K];\n append<\n K extends keyof DataAdapterType &\n { [P in keyof DataAdapterType]: DataAdapterType[P] extends string ? P : never }[keyof DataAdapterType],\n >(\n key: K,\n value: string,\n separator?: string,\n ): DataAdapterType[K];\n snapshot(): DataAdapterType;\n snapshot<K extends keyof DataAdapterType>(key?: K): DataAdapterType[K];\n onDataChange: Signal<(detail: DataChangeSignalDetail) => void>;\n clearOnResume?: boolean;\n}\n\nexport function defineData<T extends DataSchema>(data: T): T {\n return data;\n}\n\n/**\n * An in-memory game-data plugin with optional localStorage backup.\n *\n * Not `IStorageCapability` — its API (`get`/`set`/`increment`/...) is richer\n * than the generic save/load contract. Accessed directly via `app.data`.\n */\nexport class DataAdapter extends Plugin<Partial<IDataAdapterOptions>> implements IDataAdapter {\n public data: DataAdapterType;\n\n public onDataChange: Signal<(detail: DataChangeSignalDetail) => void> = new Signal();\n\n private backupKeys: Array<keyof DataAdapterType> = [];\n private backupAll: boolean = false;\n private namespace: string = '';\n private overrideWithLocalStorage: boolean = true;\n\n constructor(id: string = 'data') {\n super(id);\n }\n\n public getCoreSignals(): string[] {\n return ['onDataChange'];\n }\n\n destroy() {\n this.data = {} as DataAdapterType;\n }\n\n public initialize(options?: Partial<IDataAdapterOptions>): void {\n this.namespace = options?.namespace || this.app.appName;\n this.data = (options?.initial as DataAdapterType) || ({} as DataAdapterType);\n this.backupKeys = options?.backupKeys || [];\n this.backupAll = options?.backupAll || false;\n this.overrideWithLocalStorage = options?.overrideWithLocalStorage === false ? false : true;\n\n if (this.backupAll || this.backupKeys.length > 0) {\n if (this.overrideWithLocalStorage) {\n this.restoreFromLocalStorage(this.backupKeys);\n }\n this.backupToLocalStorage(this.backupKeys);\n }\n }\n\n set<K extends keyof DataAdapterType>(key: K, data: DataAdapterType[K]): DataAdapterType;\n set(data: DeepPartial<DataAdapterType>, merge?: boolean): DataAdapterType;\n set<K extends keyof DataAdapterType>(\n keyOrData: K | DeepPartial<DataAdapterType>,\n dataOrMerge?: DataAdapterType[K] | boolean,\n ): DataAdapterType {\n if (typeof keyOrData === 'string' || typeof keyOrData === 'number' || typeof keyOrData === 'symbol') {\n const key = keyOrData;\n const data = dataOrMerge as DataAdapterType[K];\n\n this.data[key] = data;\n if (this.backupAll || this.backupKeys.includes(key)) {\n this.backupToLocalStorage([key]);\n }\n this.onDataChange.emit({ key, value: data });\n return this.data;\n }\n\n const data = keyOrData as DeepPartial<DataAdapterType>;\n const merge = (dataOrMerge as boolean) ?? true;\n\n if (merge) {\n this.data = deepMerge({ ...this.data }, data);\n } else {\n this.data = data as DataAdapterType;\n }\n\n if (this.backupAll || this.backupKeys.length > 0) {\n this.backupToLocalStorage(this.backupKeys);\n }\n\n this.onDataChange.emit({\n key: Object.keys(data)?.length === 1 ? Object.keys(data)[0] : Object.keys(data),\n value: data[Object.keys(data)[0]] as DataAdapterType[keyof DataAdapterType],\n });\n\n return this.data;\n }\n\n get(): DataAdapterType;\n get<K extends keyof DataAdapterType>(key?: K): DataAdapterType[K] | undefined;\n get<K extends keyof DataAdapterType>(key?: K): DataAdapterType[K] | DataAdapterType | undefined {\n if (key === undefined) {\n return this.data;\n }\n return this.data[key];\n }\n\n increment<\n K extends keyof DataAdapterType &\n { [P in keyof DataAdapterType]: DataAdapterType[P] extends number ? P : never }[keyof DataAdapterType],\n >(key: K, amount: number = 1): DataAdapterType[K] {\n const currentValue = this.data[key] || 0;\n const newValue = currentValue + amount;\n this.set({ [key]: newValue } as DeepPartial<DataAdapterType>);\n return newValue as DataAdapterType[K];\n }\n\n concat<\n K extends keyof DataAdapterType &\n { [P in keyof DataAdapterType]: DataAdapterType[P] extends any[] ? P : never }[keyof DataAdapterType],\n >(key: K, value: DataAdapterType[K] extends (infer E)[] ? E | E[] : never): DataAdapterType[K] {\n const currentValue = this.data[key];\n const newValue = [...currentValue, ...(Array.isArray(value) ? value : [value])];\n this.set({ [key]: newValue } as DeepPartial<DataAdapterType>);\n return newValue as DataAdapterType[K];\n }\n\n append<\n K extends keyof DataAdapterType &\n { [P in keyof DataAdapterType]: DataAdapterType[P] extends string ? P : never }[keyof DataAdapterType],\n >(key: K, value: string, separator: string = ''): DataAdapterType[K] {\n const currentValue = this.data[key];\n let newValue = value;\n if ((currentValue as string)?.length > 0) {\n newValue = currentValue + separator + value;\n }\n this.set({ [key]: newValue } as DeepPartial<DataAdapterType>);\n return newValue as DataAdapterType[K];\n }\n\n clear(): void;\n clear<K extends keyof DataAdapterType>(key?: K): void {\n if (key === undefined) {\n this.data = {} as DataAdapterType;\n localStorage.clear();\n this.onDataChange.emit({ key, clear: true });\n } else {\n delete this.data[key];\n localStorage.removeItem(`${this.namespace}-${key as string}`);\n this.onDataChange.emit({ clear: true });\n }\n }\n\n snapshot(): DataAdapterType;\n snapshot<K extends keyof DataAdapterType>(key?: K): DataAdapterType[K];\n snapshot<K extends keyof DataAdapterType>(key?: K): DataAdapterType[K] | DataAdapterType {\n if (key === undefined) {\n return JSON.parse(JSON.stringify(this.data));\n }\n return JSON.parse(JSON.stringify(this.data[key]));\n }\n\n private backupToLocalStorage(keys?: Array<keyof DataAdapterType>): void {\n const dataToBackup =\n keys && keys?.length > 0 ? Object.fromEntries(keys.map((key) => [key, this.data[key]])) : this.data;\n\n for (const key in dataToBackup) {\n localStorage.setItem(`${this.namespace}-${key}`, JSON.stringify(dataToBackup[key]));\n }\n }\n\n private restoreFromLocalStorage(keys?: Array<keyof DataAdapterType>): void {\n const keysToRestore = keys && keys?.length > 0 ? keys : (Object.keys(this.data) as Array<keyof DataAdapterType>);\n keysToRestore.forEach((key) => {\n try {\n const loadedData = localStorage.getItem(`${this.namespace}-${String(key)}`);\n if (loadedData !== null) {\n try {\n const parsedData = JSON.parse(loadedData);\n this.data[key] = parsedData;\n } catch (parseError) {\n console.warn(\n `Failed to parse data for key \"${String(key)}\" in namespace \"${this.namespace}\". Using default value.`,\n );\n }\n }\n } catch (storageError) {\n console.error(\n `Error accessing localStorage for key \"${String(key)}\" in namespace \"${this.namespace}\":`,\n storageError,\n );\n }\n });\n this.onDataChange.emit({ restore: true });\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DataAdapter-BZFTkFQ4.js","names":[],"sources":["../src/plugins/DataAdapter.ts"],"sourcesContent":["import { Signal } from '../signals';\nimport { AppTypeOverrides, deepMerge, DeepPartial } from '../utils';\nimport { Plugin } from './Plugin';\n\nexport type DataSchema = {\n [key: string]: any;\n};\n\n/**\n * Interface for the options of the DataAdapter.\n */\nexport interface IDataAdapterOptions {\n initial: Partial<AppTypeOverrides['Data']>;\n /**\n * The namespace to use for the keys in local storage.\n */\n namespace: string;\n /**\n * Whether to override the data with the data from local storage.\n */\n overrideWithLocalStorage: boolean;\n /**\n * Whether to backup all data to local storage.\n */\n backupAll: boolean;\n /**\n * The keys to backup to local storage.\n */\n backupKeys: Array<keyof AppTypeOverrides['Data']>;\n}\n\nexport interface DataChangeSignalDetail {\n key?: any;\n value?: any;\n restore?: boolean;\n clear?: boolean;\n}\n\ntype DataAdapterType = AppTypeOverrides['Data'];\n\nexport interface IDataAdapter {\n get(): DataAdapterType;\n get<K extends keyof DataAdapterType>(key: K): DataAdapterType[K] | undefined;\n set<K extends keyof DataAdapterType>(key: K, data: DataAdapterType[K]): DataAdapterType;\n set(data: DeepPartial<DataAdapterType>, merge?: boolean): DataAdapterType;\n clear(): void;\n clear<K extends keyof DataAdapterType>(key: K): void;\n increment<\n K extends keyof DataAdapterType &\n { [P in keyof DataAdapterType]: DataAdapterType[P] extends number ? P : never }[keyof DataAdapterType],\n >(\n key: K,\n amount?: number,\n ): DataAdapterType[K];\n concat<\n K extends keyof DataAdapterType &\n { [P in keyof DataAdapterType]: DataAdapterType[P] extends any[] ? P : never }[keyof DataAdapterType],\n >(\n key: K,\n value: DataAdapterType[K] extends (infer E)[] ? E | E[] : never,\n ): DataAdapterType[K];\n append<\n K extends keyof DataAdapterType &\n { [P in keyof DataAdapterType]: DataAdapterType[P] extends string ? P : never }[keyof DataAdapterType],\n >(\n key: K,\n value: string,\n separator?: string,\n ): DataAdapterType[K];\n snapshot(): DataAdapterType;\n snapshot<K extends keyof DataAdapterType>(key?: K): DataAdapterType[K];\n onDataChange: Signal<(detail: DataChangeSignalDetail) => void>;\n clearOnResume?: boolean;\n}\n\nexport function defineData<T extends DataSchema>(data: T): T {\n return data;\n}\n\n/**\n * An in-memory game-data plugin with optional localStorage backup.\n *\n * Not `IStorageCapability` — its API (`get`/`set`/`increment`/...) is richer\n * than the generic save/load contract. Accessed directly via `app.data`.\n */\nexport class DataAdapter extends Plugin<Partial<IDataAdapterOptions>> implements IDataAdapter {\n public data: DataAdapterType;\n\n public onDataChange: Signal<(detail: DataChangeSignalDetail) => void> = new Signal();\n\n private backupKeys: Array<keyof DataAdapterType> = [];\n private backupAll: boolean = false;\n private namespace: string = '';\n private overrideWithLocalStorage: boolean = true;\n\n constructor(id: string = 'data') {\n super(id);\n }\n\n public getCoreSignals(): string[] {\n return ['onDataChange'];\n }\n\n destroy() {\n this.data = {} as DataAdapterType;\n }\n\n public initialize(options?: Partial<IDataAdapterOptions>): void {\n this.namespace = options?.namespace || this.app.appName;\n this.data = (options?.initial as DataAdapterType) || ({} as DataAdapterType);\n this.backupKeys = options?.backupKeys || [];\n this.backupAll = options?.backupAll || false;\n this.overrideWithLocalStorage = options?.overrideWithLocalStorage === false ? false : true;\n\n if (this.backupAll || this.backupKeys.length > 0) {\n if (this.overrideWithLocalStorage) {\n this.restoreFromLocalStorage(this.backupKeys);\n }\n this.backupToLocalStorage(this.backupKeys);\n }\n }\n\n set<K extends keyof DataAdapterType>(key: K, data: DataAdapterType[K]): DataAdapterType;\n set(data: DeepPartial<DataAdapterType>, merge?: boolean): DataAdapterType;\n set<K extends keyof DataAdapterType>(\n keyOrData: K | DeepPartial<DataAdapterType>,\n dataOrMerge?: DataAdapterType[K] | boolean,\n ): DataAdapterType {\n if (typeof keyOrData === 'string' || typeof keyOrData === 'number' || typeof keyOrData === 'symbol') {\n const key = keyOrData;\n const data = dataOrMerge as DataAdapterType[K];\n\n this.data[key] = data;\n if (this.backupAll || this.backupKeys.includes(key)) {\n this.backupToLocalStorage([key]);\n }\n this.onDataChange.emit({ key, value: data });\n return this.data;\n }\n\n const data = keyOrData as DeepPartial<DataAdapterType>;\n const merge = (dataOrMerge as boolean) ?? true;\n\n if (merge) {\n this.data = deepMerge({ ...this.data }, data);\n } else {\n this.data = data as DataAdapterType;\n }\n\n if (this.backupAll || this.backupKeys.length > 0) {\n this.backupToLocalStorage(this.backupKeys);\n }\n\n this.onDataChange.emit({\n key: Object.keys(data)?.length === 1 ? Object.keys(data)[0] : Object.keys(data),\n value: data[Object.keys(data)[0]] as DataAdapterType[keyof DataAdapterType],\n });\n\n return this.data;\n }\n\n get(): DataAdapterType;\n get<K extends keyof DataAdapterType>(key?: K): DataAdapterType[K] | undefined;\n get<K extends keyof DataAdapterType>(key?: K): DataAdapterType[K] | DataAdapterType | undefined {\n if (key === undefined) {\n return this.data;\n }\n return this.data[key];\n }\n\n increment<\n K extends keyof DataAdapterType &\n { [P in keyof DataAdapterType]: DataAdapterType[P] extends number ? P : never }[keyof DataAdapterType],\n >(key: K, amount: number = 1): DataAdapterType[K] {\n const currentValue = this.data[key] || 0;\n const newValue = currentValue + amount;\n this.set({ [key]: newValue } as DeepPartial<DataAdapterType>);\n return newValue as DataAdapterType[K];\n }\n\n concat<\n K extends keyof DataAdapterType &\n { [P in keyof DataAdapterType]: DataAdapterType[P] extends any[] ? P : never }[keyof DataAdapterType],\n >(key: K, value: DataAdapterType[K] extends (infer E)[] ? E | E[] : never): DataAdapterType[K] {\n const currentValue = this.data[key];\n const newValue = [...currentValue, ...(Array.isArray(value) ? value : [value])];\n this.set({ [key]: newValue } as DeepPartial<DataAdapterType>);\n return newValue as DataAdapterType[K];\n }\n\n append<\n K extends keyof DataAdapterType &\n { [P in keyof DataAdapterType]: DataAdapterType[P] extends string ? P : never }[keyof DataAdapterType],\n >(key: K, value: string, separator: string = ''): DataAdapterType[K] {\n const currentValue = this.data[key];\n let newValue = value;\n if ((currentValue as string)?.length > 0) {\n newValue = currentValue + separator + value;\n }\n this.set({ [key]: newValue } as DeepPartial<DataAdapterType>);\n return newValue as DataAdapterType[K];\n }\n\n clear(): void;\n clear<K extends keyof DataAdapterType>(key?: K): void {\n if (key === undefined) {\n this.data = {} as DataAdapterType;\n localStorage.clear();\n this.onDataChange.emit({ key, clear: true });\n } else {\n delete this.data[key];\n localStorage.removeItem(`${this.namespace}-${key as string}`);\n this.onDataChange.emit({ clear: true });\n }\n }\n\n snapshot(): DataAdapterType;\n snapshot<K extends keyof DataAdapterType>(key?: K): DataAdapterType[K];\n snapshot<K extends keyof DataAdapterType>(key?: K): DataAdapterType[K] | DataAdapterType {\n if (key === undefined) {\n return JSON.parse(JSON.stringify(this.data));\n }\n return JSON.parse(JSON.stringify(this.data[key]));\n }\n\n private backupToLocalStorage(keys?: Array<keyof DataAdapterType>): void {\n const dataToBackup =\n keys && keys?.length > 0 ? Object.fromEntries(keys.map((key) => [key, this.data[key]])) : this.data;\n\n for (const key in dataToBackup) {\n localStorage.setItem(`${this.namespace}-${key}`, JSON.stringify(dataToBackup[key]));\n }\n }\n\n private restoreFromLocalStorage(keys?: Array<keyof DataAdapterType>): void {\n const keysToRestore = keys && keys?.length > 0 ? keys : (Object.keys(this.data) as Array<keyof DataAdapterType>);\n keysToRestore.forEach((key) => {\n try {\n const loadedData = localStorage.getItem(`${this.namespace}-${String(key)}`);\n if (loadedData !== null) {\n try {\n const parsedData = JSON.parse(loadedData);\n this.data[key] = parsedData;\n } catch (parseError) {\n console.warn(\n `Failed to parse data for key \"${String(key)}\" in namespace \"${this.namespace}\". Using default value.`,\n );\n }\n }\n } catch (storageError) {\n console.error(\n `Error accessing localStorage for key \"${String(key)}\" in namespace \"${this.namespace}\":`,\n storageError,\n );\n }\n });\n this.onDataChange.emit({ restore: true });\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Tn as e } from "./registries-qQmLeN0b.js";
|
|
2
2
|
import { BigPool as t, Bounds as n, Container as r, Graphics as i, Rectangle as a } from "pixi.js";
|
|
3
3
|
//#region ../../node_modules/.pnpm/yoga-layout@3.2.1/node_modules/yoga-layout/dist/binaries/yoga-wasm-base64-esm.js
|
|
4
4
|
var o = (() => {
|
|
@@ -1382,4 +1382,4 @@ var se = class extends r {
|
|
|
1382
1382
|
//#endregion
|
|
1383
1383
|
export { s as a, d as c, g as d, _ as f, C as h, re as i, f as l, x as m, w as n, c as o, b as p, E as r, u as s, ce as t, h as u };
|
|
1384
1384
|
|
|
1385
|
-
//# sourceMappingURL=DebugRenderer-
|
|
1385
|
+
//# sourceMappingURL=DebugRenderer-C7X-nlXE.js.map
|