@rb-games/core 0.1.3 → 0.1.4
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/dist/{chunk-DOHQE2YZ.js → chunk-C45KDREE.js} +46 -50
- package/dist/chunk-C45KDREE.js.map +1 -0
- package/dist/{chunk-RAEOBW6E.js → chunk-P4GCINNA.js} +3 -3
- package/dist/{chunk-RAEOBW6E.js.map → chunk-P4GCINNA.js.map} +1 -1
- package/dist/{chunk-YSLGJAV6.js → chunk-XHUPUPPW.js} +3 -5
- package/dist/chunk-XHUPUPPW.js.map +1 -0
- package/dist/engine/index.js +5 -6
- package/dist/engine/index.js.map +1 -1
- package/dist/helpers/index.js +4 -4
- package/dist/helpers/index.js.map +1 -1
- package/dist/i18n/index.js +2 -2
- package/dist/particle/index.js +109 -476
- package/dist/particle/index.js.map +1 -1
- package/dist/plugins/index.js +157 -202
- package/dist/plugins/index.js.map +1 -1
- package/dist/state-machine/index.js +7 -9
- package/dist/state-machine/index.js.map +1 -1
- package/dist/store/index.js +3 -4
- package/dist/store/index.js.map +1 -1
- package/dist/ui/components/Skinable.d.ts.map +1 -1
- package/dist/ui/index.js +142 -191
- package/dist/ui/index.js.map +1 -1
- package/dist/utils/index.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-DOHQE2YZ.js.map +0 -1
- package/dist/chunk-YSLGJAV6.js.map +0 -1
package/dist/helpers/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { resolvePublicPath } from '../chunk-NQMORMNP.js';
|
|
2
|
-
import { darkenColor, lightenColor } from '../chunk-
|
|
3
|
-
import '../chunk-
|
|
2
|
+
import { darkenColor, lightenColor } from '../chunk-XHUPUPPW.js';
|
|
3
|
+
import '../chunk-C45KDREE.js';
|
|
4
4
|
import '../chunk-5BLUF2HG.js';
|
|
5
5
|
import { require_lodash } from '../chunk-NAQG7TMS.js';
|
|
6
6
|
import { __toESM } from '../chunk-G3PMV62Z.js';
|
|
@@ -126,7 +126,6 @@ function configureSVGParser(config) {
|
|
|
126
126
|
|
|
127
127
|
// helpers/SVGLoader.ts
|
|
128
128
|
var SVGLoader = class {
|
|
129
|
-
static installed = false;
|
|
130
129
|
/**
|
|
131
130
|
* Installs the SVG loader into the PixiJS Assets system.
|
|
132
131
|
*
|
|
@@ -174,8 +173,8 @@ var SVGLoader = class {
|
|
|
174
173
|
console.log("SVG Loader uninstalled");
|
|
175
174
|
}
|
|
176
175
|
};
|
|
176
|
+
SVGLoader.installed = false;
|
|
177
177
|
var SVGAssetHelper = class {
|
|
178
|
-
static themeColor = "#4CAF50";
|
|
179
178
|
/**
|
|
180
179
|
* Sets the global theme color for all SVG assets.
|
|
181
180
|
*
|
|
@@ -540,6 +539,7 @@ var SVGAssetHelper = class {
|
|
|
540
539
|
return hashHex.substring(0, 12);
|
|
541
540
|
}
|
|
542
541
|
};
|
|
542
|
+
SVGAssetHelper.themeColor = "#4CAF50";
|
|
543
543
|
function generateButtonSkinFromAsset(backgroundName, iconName, buttonStates = ["up", "over", "down", "disabled"], iconStates) {
|
|
544
544
|
const skinData = {};
|
|
545
545
|
buttonStates.forEach((state) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../helpers/SVGParser.ts","../../helpers/SVGLoader.ts","../../helpers/SVGAssetHelper.ts","../../helpers/AssetHelper.ts","../../helpers/eventBridge.ts","../../helpers/mergeUtils.ts"],"names":["Assets","Texture"],"mappings":"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","file":"index.js","sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Texture, TextureSource, LoaderParser, ExtensionType, ResolvedAsset } from 'pixi.js';\n// @ts-ignore\nimport { minimatch } from 'minimatch';\n\n/**\n * Style definitions for SVG elements using CSS selectors.\n *\n * Maps CSS selectors to attribute-value pairs that will be applied to matching SVG elements.\n * Commonly used for dynamic theming and color changes.\n *\n * @example\n * ```typescript\n * const styles: SVGStyleData = {\n * '#primary': { fill: '#4CAF50', stroke: '#388E3C' },\n * '.icon': { fill: '#FFFFFF' },\n * 'circle': { opacity: '0.8' }\n * };\n * ```\n *\n * @public\n */\nexport interface SVGStyleData {\n /** CSS selector as key, attributes as value */\n [selector: string]: {\n /** SVG attribute name (e.g., 'fill', 'stroke', 'opacity') */\n [attribute: string]: string;\n };\n}\n\n/**\n * Configuration data for loading and processing SVG files.\n *\n * This interface defines all options available when loading an SVG asset,\n * including styling, sizing, and resolution settings.\n *\n * @example\n * ```typescript\n * const loadData: SVGLoadData = {\n * styles: {\n * '#background': { fill: '#4CAF50' },\n * '#icon': { fill: '#FFFFFF' }\n * },\n * size: { width: 128, height: 128 },\n * resolution: 2\n * };\n * ```\n *\n * @public\n */\nexport interface SVGLoadData {\n /** Style definitions to apply to SVG elements */\n styles?: SVGStyleData;\n /** Target size for rasterization (width and height in pixels) */\n size?: { width: number; height: number };\n /** Resolution multiplier for high-DPI displays (default: 1) */\n resolution?: number;\n /** Button states for multi-state assets (used by SVGAssetHelper) */\n states?: string[];\n}\n\n/**\n * Global configuration for the SVG parser.\n *\n * @public\n */\nexport interface SVGParserConfig {\n /** Glob pattern to match SVG files (uses minimatch) */\n testPattern?: string;\n}\n\n// Parser global configuration\nlet parserConfig: SVGParserConfig = {};\n\n/**\n * Manipulates SVG string by applying styles and size modifications.\n *\n * This function parses the SVG string, applies CSS selector-based styles,\n * and optionally resizes the SVG before returning the modified string.\n *\n * @param svgString - Raw SVG file content as string\n * @param data - Optional load data with styles and size\n * @returns Modified SVG string\n *\n * @internal\n */\nfunction manipulateSVG(svgString: string, data?: SVGLoadData): string {\n const parser = new DOMParser();\n const svgDoc = parser.parseFromString(svgString, 'image/svg+xml');\n const svgElement = svgDoc.documentElement;\n\n // Apply styles\n if (data?.styles) {\n Object.entries(data.styles).forEach(([selector, styles]) => {\n const elements = svgDoc.querySelectorAll(selector);\n elements.forEach((element) => {\n Object.entries(styles).forEach(([attr, value]) => {\n element.setAttribute(attr, value);\n });\n });\n });\n }\n\n // Set size\n if (data?.size) {\n svgElement.setAttribute('width', data.size.width.toString());\n svgElement.setAttribute('height', data.size.height.toString());\n\n // Optionally update the viewBox as well\n // const viewBox = svgElement.getAttribute('viewBox');\n // if (viewBox) {\n // const [x, y] = viewBox.split(' ');\n // svgElement.setAttribute('viewBox', `${x} ${y} ${data.size.width} ${data.size.height}`);\n // }\n }\n\n return new XMLSerializer().serializeToString(svgDoc);\n}\n\n/**\n * Converts an SVG string to a PixiJS Texture by rasterizing it to a canvas.\n *\n * This function creates an Image element from the SVG, draws it to a canvas,\n * and generates a PixiJS Texture from the canvas. Supports resolution scaling\n * for high-DPI displays.\n *\n * @param svgString - SVG content as string\n * @param data - Optional load data with resolution settings\n * @returns Promise that resolves to a PixiJS Texture\n *\n * @internal\n */\nasync function createTextureFromSVG(svgString: string, data?: SVGLoadData): Promise<Texture> {\n const blob = new Blob([svgString], { type: 'image/svg+xml' });\n const url = URL.createObjectURL(blob);\n\n const img = new Image();\n img.src = url;\n\n return new Promise((resolve, reject) => {\n img.onload = () => {\n try {\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n\n if (!ctx) {\n reject(new Error('Could not get canvas context'));\n return;\n }\n\n const resolution = data?.resolution || 1;\n canvas.width = img.width * resolution;\n canvas.height = img.height * resolution;\n\n //ctx.scale(resolution, resolution);\n ctx.drawImage(img, 0, 0);\n\n const source = TextureSource.from(canvas);\n const texture = new Texture(source);\n resolve(texture);\n URL.revokeObjectURL(url);\n } catch (error) {\n reject(error);\n }\n };\n\n img.onerror = () => {\n URL.revokeObjectURL(url);\n reject(new Error('Failed to load SVG image'));\n };\n });\n}\n\n/**\n * PixiJS LoaderParser implementation for SVG files.\n *\n * This parser integrates with PixiJS Assets system to automatically detect,\n * load, and process SVG files as textures. It handles:\n * - SVG file detection via URL pattern matching\n * - Style manipulation using CSS selectors\n * - Size and resolution configuration\n * - Canvas rasterization for texture generation\n *\n * The parser is registered with PixiJS Assets via SVGLoader.install().\n *\n * @remarks\n * This parser uses DOMParser and Canvas API to convert SVG to raster textures.\n * All SVG manipulations happen before rasterization, ensuring clean output.\n *\n * @example\n * ```typescript\n * // Parser is automatically used after SVGLoader.install()\n * await Assets.load({\n * alias: 'icon',\n * src: 'assets/icon.svg',\n * data: {\n * styles: { '#primary': { fill: '#4CAF50' } },\n * size: { width: 64, height: 64 },\n * resolution: 2\n * }\n * });\n * ```\n *\n * @public\n */\nexport const SVGParser: LoaderParser<Texture, SVGLoadData> = {\n /**\n * Extension metadata for the parser.\n *\n * @internal\n */\n extension: {\n type: ExtensionType.LoadParser,\n name: 'svgParser',\n priority: 0,\n },\n\n /**\n * Unique identifier for the parser.\n *\n * @internal\n */\n id: 'svgParser',\n\n /**\n * Tests if a URL should be handled by this parser.\n *\n * By default, matches files ending with .svg extension.\n * Can be customized via configureSVGParser() with a glob pattern.\n *\n * @param url - Asset URL to test\n * @returns True if this parser should handle the URL\n */\n test: (url: string) => {\n // If a custom pattern is provided, use it\n if (parserConfig.testPattern) {\n try {\n const urlObj = new URL(url);\n const pathname = urlObj.pathname.startsWith('/')\n ? urlObj.pathname.slice(1)\n : urlObj.pathname;\n return minimatch(pathname, parserConfig.testPattern, { partial: true });\n } catch {\n // If URL parsing fails, try with the original string\n return minimatch(url, parserConfig.testPattern, { partial: true });\n }\n }\n\n // Default: check that the file actually ends with .svg\n return /\\.svg$/i.test(url);\n },\n\n /**\n * Loads and processes an SVG file into a PixiJS Texture.\n *\n * This method:\n * 1. Fetches the SVG file from the URL\n * 2. Applies style and size manipulations\n * 3. Rasterizes the SVG to a canvas\n * 4. Creates a PixiJS Texture from the canvas\n *\n * @param url - URL of the SVG file to load\n * @param resolvedAsset - Resolved asset with optional load data\n * @returns Promise that resolves to a PixiJS Texture\n */\n async load(url: string, resolvedAsset?: ResolvedAsset<SVGLoadData>): Promise<Texture> {\n // Fetch the SVG file\n const response = await fetch(url);\n const svgString = await response.text();\n\n // Manipulate the SVG\n const manipulatedSVG = manipulateSVG(svgString, resolvedAsset?.data);\n\n // Convert to Texture\n const texture = await createTextureFromSVG(manipulatedSVG, resolvedAsset?.data);\n texture.label = resolvedAsset?.src ?? 'unknown';\n return texture;\n },\n};\n\n/**\n * Configures the SVG parser with global settings.\n *\n * This function allows customization of the parser behavior, such as\n * specifying custom glob patterns for SVG file matching.\n *\n * Typically called by SVGLoader.install() but can be used independently.\n *\n * @param config - Parser configuration options\n *\n * @example\n * ```typescript\n * configureSVGParser({\n * testPattern: 'assets/svg/*.svg'\n * });\n * ```\n *\n * @public\n */\nexport function configureSVGParser(config: SVGParserConfig): void {\n parserConfig = { ...parserConfig, ...config };\n}\n","import { Assets } from 'pixi.js';\nimport { SVGParser, configureSVGParser } from './SVGParser';\n\n/**\n * Configuration options for the SVG loader.\n */\nexport interface SVGLoaderConfig {\n /** Glob pattern to match SVG files (uses minimatch) */\n testPattern?: string;\n}\n\n/**\n * SVG loader plugin for PixiJS Assets system.\n *\n * SVGLoader integrates the SVG parser into PixiJS asset loading pipeline,\n * enabling automatic loading and processing of SVG files as textures.\n *\n * @remarks\n * Install once at application startup using SVGLoader.install().\n * After installation, SVG files can be loaded using PixiJS Assets API or SVGAssetHelper.\n *\n * @public\n */\nexport class SVGLoader {\n private static installed = false;\n\n /**\n * Installs the SVG loader into the PixiJS Assets system.\n *\n * This method must be called once at application startup before loading any SVG assets.\n * It registers the SVG parser with PixiJS, enabling automatic SVG file processing.\n * This method is idempotent - calling it multiple times is safe but only the first call will take effect.\n *\n * @param config - Optional configuration for SVG file matching\n */\n static install(config?: SVGLoaderConfig): void {\n if (this.installed) {\n console.warn('SVGLoader is already installed');\n return;\n }\n\n // Configure parser if options provided\n if (config) {\n configureSVGParser(config);\n }\n\n // Add parser to Assets loader\n Assets.loader.parsers.unshift(SVGParser);\n\n this.installed = true;\n console.log('SVG Loader installed successfully');\n }\n\n /**\n * Checks if the SVG loader has been installed.\n *\n * @returns True if the loader is installed, false otherwise\n */\n static isInstalled(): boolean {\n return this.installed;\n }\n\n /**\n * Uninstalls the SVG loader from the PixiJS Assets system.\n *\n * This method is primarily intended for testing purposes.\n * In production, you typically install the loader once and never uninstall it.\n */\n static uninstall(): void {\n if (!this.installed) {\n return;\n }\n\n // Remove parser from Assets loader\n const index = Assets.loader.parsers.indexOf(SVGParser);\n if (index > -1) {\n Assets.loader.parsers.splice(index, 1);\n }\n\n this.installed = false;\n console.log('SVG Loader uninstalled');\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Assets, Cache, Color, type ColorSource } from 'pixi.js';\nimport { SVGLoadData, SVGStyleData } from './SVGParser';\nimport type { ButtonStateKey } from '../ui/components/ButtonComp';\nimport { lightenColor, darkenColor } from '../utils';\n\n/**\n * Button state styles for SVG assets.\n *\n * Defines the visual appearance of buttons in different interaction states.\n * Each state contains CSS-like style definitions for SVG elements.\n * Uses ButtonComp state names: up, down, over, disabled.\n *\n * @example\n * ```typescript\n * const buttonStyles: ButtonState = {\n * up: { '#primary': { fill: '#4CAF50' } },\n * over: { '#primary': { fill: '#66BB6A' } },\n * down: { '#primary': { fill: '#388E3C' } },\n * disabled: { '#primary': { fill: '#CCCCCC' } }\n * };\n * ```\n */\nexport interface ButtonState {\n /** Up/default state styles */\n up: SVGStyleData;\n /** Over/hover state styles */\n over: SVGStyleData;\n /** Down/pressed state styles */\n down: SVGStyleData;\n /** Disabled state styles (optional) */\n disabled?: SVGStyleData;\n /** Selected up state styles */\n selected_up?: SVGStyleData;\n /** Selected over state styles */\n selected_over?: SVGStyleData;\n /** Selected down state styles */\n selected_down?: SVGStyleData;\n /** Selected disabled state styles */\n selected_disabled?: SVGStyleData;\n}\n\n/**\n * Configuration for loading SVG assets.\n *\n * @example\n * ```typescript\n * const config: SVGAssetConfig = {\n * alias: 'play_button',\n * src: 'assets/svg/buttons/play.svg',\n * size: { width: 120, height: 120 },\n * resolution: 2,\n * themeColor: '#4CAF50',\n * states: ['up', 'over', 'down']\n * };\n * ```\n */\nexport interface SVGAssetConfig {\n /** Unique identifier for the asset */\n alias: string;\n /** Path to the SVG file */\n src: string;\n /** Target size for rasterization */\n size?: { width: number; height: number };\n /** Resolution multiplier for high-DPI displays */\n resolution?: number;\n /** Theme color for styling (supports all PixiJS ColorSource formats) */\n themeColor?: ColorSource;\n /** Button states to generate (e.g., ['up', 'over', 'down', 'disabled']) */\n states?: ButtonStateKey[];\n}\n\n/**\n * High-level utility for loading and managing SVG assets in PixiJS.\n *\n * SVGAssetHelper provides a convenient API for loading SVG files as PixiJS textures\n * with automatic theming, button state management, and batch loading capabilities.\n *\n * ## Features\n *\n * - **Theme Support**: Global and per-asset theme colors\n * - **Button States**: Automatic generation of up, over, down, disabled states\n * - **Batch Loading**: Load multiple assets efficiently\n * - **Color Manipulation**: Automatic lighten/darken for button states\n * - **Cache Management**: Check and clear loaded assets\n * - **Custom Styles**: Create custom style configurations\n *\n * ## Workflow\n *\n * 1. **Initialize**: Set global theme color (optional)\n * 2. **Load**: Load SVG assets with configuration\n * 3. **Use**: Retrieve textures and create sprites\n * 4. **Manage**: Check cache and clear unused assets\n *\n * @example\n * ```typescript\n * import { SVGAssetHelper, SVGLoader } from '@rb-games/core/helpers';\n * import { Sprite } from 'pixi.js';\n *\n * // Initialize SVG system\n * SVGLoader.install();\n * SVGAssetHelper.setThemeColor('#4CAF50');\n *\n * // Load a simple icon\n * await SVGAssetHelper.loadSVGAsset({\n * alias: 'settings_icon',\n * src: 'assets/svg/settings.svg',\n * size: { width: 48, height: 48 },\n * themeColor: '#2196F3'\n * });\n *\n * // Create sprite\n * const icon = new Sprite(SVGAssetHelper.getAsset('settings_icon'));\n * ```\n *\n * @example\n * ```typescript\n * // Load button with states\n * await SVGAssetHelper.loadButtonAsset({\n * alias: 'play_btn',\n * src: 'assets/svg/play.svg',\n * size: { width: 120, height: 120 },\n * themeColor: '#4CAF50',\n * states: ['up', 'over', 'down']\n * });\n *\n * // Create interactive button\n * const button = new Sprite(SVGAssetHelper.getAsset('play_btn', 'up'));\n * button.eventMode = 'static';\n * button.cursor = 'pointer';\n *\n * button.on('pointerover', () => {\n * button.texture = SVGAssetHelper.getAsset('play_btn', 'over');\n * });\n *\n * button.on('pointerout', () => {\n * button.texture = SVGAssetHelper.getAsset('play_btn', 'up');\n * });\n * ```\n *\n * @example\n * ```typescript\n * // Batch load multiple assets\n * await SVGAssetHelper.loadBatchAssets([\n * {\n * alias: 'star_icon',\n * src: 'assets/svg/icons/star.svg',\n * size: { width: 32, height: 32 },\n * themeColor: '#FFD700'\n * },\n * {\n * alias: 'close_btn',\n * src: 'assets/svg/buttons/close.svg',\n * size: { width: 40, height: 40 },\n * states: ['up', 'over'],\n * themeColor: '#F44336'\n * }\n * ]);\n * ```\n *\n * @public\n */\nexport class SVGAssetHelper {\n private static themeColor: ColorSource = '#4CAF50';\n\n /**\n * Sets the global theme color for all SVG assets.\n *\n * This color will be used as the default for all assets unless overridden\n * in individual asset configurations.\n *\n * @param color - Theme color (supports all PixiJS ColorSource formats)\n *\n * @example\n * ```typescript\n * // Set theme with hex string\n * SVGAssetHelper.setThemeColor('#4CAF50');\n *\n * // Set theme with number\n * SVGAssetHelper.setThemeColor(0x4CAF50);\n *\n * // Set theme with RGB array\n * SVGAssetHelper.setThemeColor([0.3, 0.69, 0.31]);\n * ```\n */\n static setThemeColor(color: ColorSource): void {\n this.themeColor = color;\n }\n\n /**\n * Gets the current global theme color.\n *\n * @returns The current theme color as ColorSource\n *\n * @example\n * ```typescript\n * const currentTheme = SVGAssetHelper.getThemeColor();\n * // Can be used directly or converted as needed\n * const hex = new Color(currentTheme).toHex();\n * ```\n */\n static getThemeColor(): ColorSource {\n return this.themeColor;\n }\n\n /**\n * Create button state styles based on theme color\n */\n static createButtonStyles(\n themeColor?: ColorSource,\n variations?: { /** lighten amount */ over: number; /** darken amount */ down: number },\n ): ButtonState {\n const baseColor = themeColor || this.themeColor;\n const baseColorHex = new Color(baseColor).toHex();\n\n return {\n up: {\n '#primary': { fill: baseColorHex },\n '#secondary': { fill: '#ffffff' },\n '#background': { fill: baseColorHex },\n },\n over: {\n '#primary': { fill: lightenColor(baseColor, variations?.over || 0.15).toHex() },\n '#secondary': { fill: '#ffffff' },\n '#background': { fill: lightenColor(baseColor, variations?.over || 0.15).toHex() },\n },\n down: {\n '#primary': { fill: darkenColor(baseColor, variations?.down || 0.15).toHex() },\n '#secondary': { fill: '#ffffff' },\n '#background': { fill: darkenColor(baseColor, variations?.down || 0.15).toHex() },\n },\n disabled: {\n '#primary': { fill: '#cccccc' },\n '#secondary': { fill: '#999999' },\n '#background': { fill: '#cccccc' },\n },\n selected_up: {\n '#primary': { fill: baseColorHex },\n '#secondary': { fill: '#ffffff' },\n '#background': { fill: baseColorHex },\n },\n selected_over: {\n '#primary': { fill: lightenColor(baseColor, variations?.over || 0.15).toHex() },\n '#secondary': { fill: '#ffffff' },\n '#background': { fill: lightenColor(baseColor, variations?.over || 0.15).toHex() },\n },\n selected_down: {\n '#primary': { fill: darkenColor(baseColor, variations?.down || 0.15).toHex() },\n '#secondary': { fill: '#ffffff' },\n '#background': { fill: darkenColor(baseColor, variations?.down || 0.15).toHex() },\n },\n selected_disabled: {\n '#primary': { fill: '#cccccc' },\n '#secondary': { fill: '#999999' },\n '#background': { fill: '#cccccc' },\n },\n };\n }\n\n /**\n * Create custom styles\n */\n static createCustomStyles(config: {\n selectors: string[];\n colors: { [state: string]: string[] };\n }): { [state: string]: SVGStyleData } {\n const result: { [state: string]: SVGStyleData } = {};\n\n Object.entries(config.colors).forEach(([state, colors]) => {\n result[state] = {};\n config.selectors.forEach((selector, index) => {\n if (colors[index]) {\n result[state][selector] = { fill: colors[index] };\n }\n });\n });\n\n return result;\n }\n\n /**\n * Loads a single SVG asset as a PixiJS texture.\n *\n * This method loads an SVG file, applies optional theme colors and styles,\n * and registers it with the PixiJS Assets system for later retrieval.\n *\n * @param config - Asset configuration\n * @returns Promise that resolves when the asset is loaded\n *\n * @example\n * ```typescript\n * // Load a simple icon\n * await SVGAssetHelper.loadSVGAsset({\n * alias: 'home_icon',\n * src: 'assets/svg/home.svg',\n * size: { width: 64, height: 64 },\n * resolution: 2\n * });\n *\n * // Load with theme color\n * await SVGAssetHelper.loadSVGAsset({\n * alias: 'settings_icon',\n * src: 'assets/svg/settings.svg',\n * size: { width: 48, height: 48 },\n * themeColor: '#2196F3'\n * });\n * ```\n */\n static async loadSVGAsset(config: SVGAssetConfig): Promise<void> {\n const loadData: SVGLoadData = {\n size: config.size,\n resolution: config.resolution || 1,\n };\n\n if (config.themeColor) {\n const styles = this.createButtonStyles(config.themeColor);\n loadData.styles = styles.up;\n }\n\n await Assets.load({\n alias: config.alias,\n src: `${config.src}`,\n data: loadData,\n });\n }\n\n /**\n * Loads a button SVG asset with multiple interaction states.\n *\n * Automatically generates up, over, down, and optionally disabled states\n * by applying color variations (lighten for over, darken for down).\n * Each state is loaded as a separate texture with the naming convention `{alias}_{state}`.\n *\n * @param config - Button asset configuration\n * @returns Promise that resolves when all button states are loaded\n *\n * @example\n * ```typescript\n * // Load button with default states\n * await SVGAssetHelper.loadButtonAsset({\n * alias: 'play_btn',\n * src: 'assets/svg/play.svg',\n * size: { width: 120, height: 120 },\n * themeColor: '#4CAF50'\n * });\n *\n * // Access different states\n * const upTexture = SVGAssetHelper.getAsset('play_btn', 'up');\n * const overTexture = SVGAssetHelper.getAsset('play_btn', 'over');\n * const downTexture = SVGAssetHelper.getAsset('play_btn', 'down');\n * ```\n *\n * @example\n * ```typescript\n * // Custom states\n * await SVGAssetHelper.loadButtonAsset({\n * alias: 'custom_btn',\n * src: 'assets/svg/button.svg',\n * size: { width: 100, height: 40 },\n * themeColor: '#E91E63',\n * states: ['up', 'over', 'down', 'disabled']\n * });\n * ```\n */\n static async loadButtonAsset(config: SVGAssetConfig): Promise<void> {\n const styles = this.createButtonStyles(\n config.themeColor\n ? typeof config.themeColor === 'number'\n ? new Color(config.themeColor).toHex()\n : config.themeColor\n : undefined,\n );\n\n const states = config.states || ['up', 'over', 'down'];\n\n for (const state of states) {\n const stateStyles = styles[state as keyof ButtonState];\n if (stateStyles) {\n const loadData: SVGLoadData = {\n styles: stateStyles,\n size: config.size,\n resolution: config.resolution || 1,\n };\n\n const hash = await this.generateAssetHash(config.src, loadData);\n\n await Assets.load({\n alias: `${config.alias}_${state}`,\n src: `${config.src}?hash=${hash}`,\n data: loadData,\n });\n }\n }\n }\n\n /**\n * Loads multiple SVG assets in parallel for efficient batch loading.\n *\n * Automatically determines whether to load each asset as a simple SVG or\n * as a button with states based on the states property.\n *\n * @param basePath - Base directory path for all assets (assets without src will use basePath/alias.svg)\n * @param assets - Array of asset configurations (strings, objects, or mixed)\n * @param defaults - Optional default configuration applied to all assets\n * @returns Promise that resolves when all assets are loaded\n *\n * @example\n * ```typescript\n * // Simple string array (most convenient)\n * await SVGAssetHelper.loadBatchAssets(\n * 'assets/svg/desktop',\n * ['btn_bet_minus', 'btn_bet_plus', 'btn_spin'],\n * {\n * size: { width: 100, height: 100 },\n * states: ['up', 'over', 'down', 'disabled']\n * }\n * );\n *\n * // Mixed array (strings and objects for customization)\n * await SVGAssetHelper.loadBatchAssets(\n * 'assets/svg/desktop',\n * [\n * 'btn_bet_minus', // uses default size\n * 'btn_bet_plus', // uses default size\n * { alias: 'btn_spin', size: { width: 120, height: 120 } } // custom size\n * ],\n * {\n * size: { width: 80, height: 80 },\n * states: ['up', 'over', 'down', 'disabled']\n * }\n * );\n *\n * // All objects (full customization)\n * await SVGAssetHelper.loadBatchAssets(\n * 'assets/svg/desktop',\n * [\n * { alias: 'btn_bet_minus', size: { width: 90, height: 90 } },\n * { alias: 'btn_bet_plus' }, // uses default size\n * { alias: 'btn_spin', states: ['up', 'over'] } // custom states\n * ],\n * {\n * size: { width: 100, height: 100 },\n * states: ['up', 'over', 'down', 'disabled']\n * }\n * );\n *\n * // With full src paths (when assets are in different directories)\n * await SVGAssetHelper.loadBatchAssets(\n * '',\n * [\n * {\n * alias: 'star_icon',\n * src: 'assets/svg/icons/star.svg',\n * size: { width: 32, height: 32 },\n * themeColor: '#FFD700'\n * },\n * {\n * alias: 'close_btn',\n * src: 'assets/svg/buttons/close.svg',\n * size: { width: 40, height: 40 },\n * states: ['up', 'over'],\n * themeColor: '#F44336'\n * }\n * ]\n * );\n * ```\n */\n static async loadBatchAssets(\n basePath: string,\n assets: Array<string | Partial<SVGAssetConfig>>,\n defaults?: Partial<SVGAssetConfig>,\n ): Promise<void> {\n const defaultConfig = defaults || {};\n\n // Convert string array to asset configs\n const assetConfigs: Array<Partial<SVGAssetConfig>> = assets.map((asset) =>\n typeof asset === 'string' ? { alias: asset } : asset,\n );\n\n const configs: SVGAssetConfig[] = assetConfigs.map((asset) => ({\n alias: asset.alias!,\n src: asset.src || (basePath ? `${basePath}/${asset.alias}.svg` : asset.alias!),\n size: asset.size || defaultConfig.size,\n states: asset.states || defaultConfig.states,\n themeColor: asset.themeColor || defaultConfig.themeColor,\n resolution: asset.resolution || defaultConfig.resolution,\n })) as SVGAssetConfig[];\n\n const promises = configs.map((config) => {\n if (config.states && config.states.length > 1) {\n return this.loadButtonAsset(config);\n } else {\n return this.loadSVGAsset(config);\n }\n });\n\n await Promise.all(promises);\n }\n\n /**\n * Retrieves a loaded SVG asset texture.\n *\n * For button assets with states, specify the state parameter to get\n * the specific state texture.\n *\n * @param alias - Asset alias used during loading\n * @param state - Button state (for button assets)\n * @returns The PixiJS texture\n *\n * @example\n * ```typescript\n * // Get simple asset\n * const iconTexture = SVGAssetHelper.getAsset('home_icon');\n * const sprite = new Sprite(iconTexture);\n *\n * // Get button state\n * const upTexture = SVGAssetHelper.getAsset('play_btn', 'up');\n * const overTexture = SVGAssetHelper.getAsset('play_btn', 'over');\n * ```\n */\n static getAsset(alias: string, state?: string): any {\n const fullAlias = state ? `${alias}_${state}` : alias;\n return Assets.get(fullAlias);\n }\n\n /**\n * Check if asset exists in cache\n */\n static hasAsset(alias: string, state?: string): boolean {\n const fullAlias = state ? `${alias}_${state}` : alias;\n return Cache.has(fullAlias);\n }\n\n /**\n * Clear specific asset from cache\n */\n static clearAsset(alias: string, state?: string): void {\n const fullAlias = state ? `${alias}_${state}` : alias;\n if (Cache.has(fullAlias)) {\n Cache.remove(fullAlias);\n }\n }\n\n /**\n * Generate SHA-256 hash for asset configuration.\n * This creates a unique identifier based on the actual asset properties (src, styles, size, resolution)\n * rather than the state name, enabling efficient cache reuse when multiple states have identical configurations.\n *\n * @param src - Source path of the SVG\n * @param data - Load data containing styles, size, and resolution\n * @returns SHA-256 hash string\n */\n private static async generateAssetHash(src: string, data: SVGLoadData): Promise<string> {\n const configString = JSON.stringify({\n src,\n styles: data.styles || {},\n size: data.size || {},\n resolution: data.resolution || 1,\n });\n\n const encoder = new TextEncoder();\n const dataBuffer = encoder.encode(configString);\n const hashBuffer = await crypto.subtle.digest('SHA-256', dataBuffer);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n const hashHex = hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');\n\n return hashHex.substring(0, 12);\n }\n}\n","import { Assets, Spritesheet, Texture } from 'pixi.js';\nimport type { ButtonCompSkinData, ButtonStateKey } from '../ui/components';\n\n/**\n * Generates ButtonComp skin data from asset alias and states.\n *\n * Uses ButtonComp state keys directly (up, over, down, disabled) without any mapping.\n * Creates texture references for each state with the naming convention `{alias}_{state}`.\n *\n * @param alias - Asset alias used in texture names (e.g., 'btn_bet_minus')\n * @param states - Array of ButtonComp state names (default: ['up', 'over', 'down', 'disabled'])\n * @returns ButtonComp skin data with texture references for each state\n *\n * @example\n * ```typescript\n * // Generate skin for a button with all states\n * const decreaseButtonSkin = generateButtonSkinFromAsset('btn_bet_minus');\n * // Result: { up: { background: { texture: 'btn_bet_minus_up' } }, over: ..., down: ..., disabled: ... }\n *\n * // Generate skin for a button with custom states (only up and over)\n * const playButtonSkin = generateButtonSkinFromAsset('btn_play', undefined, ['up', 'over']);\n * // Result: { up: { background: { texture: 'btn_play_up' } }, over: { background: { texture: 'btn_play_over' } } }\n * ```\n */\nexport function generateButtonSkinFromAsset(\n backgroundName: string,\n iconName?: string,\n buttonStates: ButtonStateKey[] = ['up', 'over', 'down', 'disabled'],\n iconStates?: ButtonStateKey[],\n): ButtonCompSkinData {\n const skinData: Record<string, any> = {};\n\n // Background\n buttonStates.forEach((state) => {\n skinData[state] = {\n ...(skinData[state] ?? {}),\n background: { texture: `${backgroundName}_${state}` },\n };\n });\n\n // Icon (optional)\n if (iconName) {\n if (iconStates === undefined) {\n // Non-variant icon: apply to the same states we generated for the background\n buttonStates.forEach((state) => {\n skinData[state] = {\n ...(skinData[state] ?? {}),\n icon: { texture: iconName },\n };\n });\n } else {\n // Variant icon: only for provided icon states\n iconStates.forEach((state) => {\n skinData[state] = {\n ...(skinData[state] ?? {}),\n icon: { texture: `${iconName}_${state}` },\n };\n });\n }\n }\n\n return skinData as ButtonCompSkinData;\n}\n\n/**\n * Retrieves animation frames as PixiJS textures from various definition formats.\n *\n * This helper function supports three input formats:\n * 1. **Single texture name**: String identifier for a static sprite\n * 2. **Array of texture names**: Direct list of texture identifiers for animation\n * 3. **Spritesheet reference**: Object with `sheet` (spritesheet asset name) and `anim` (animation name)\n *\n * The function handles spritesheet parsing automatically and safely returns an empty array\n * if the definition is invalid or assets are not found.\n *\n * @param def - Animation definition in one of the supported formats:\n * - `string`: Single texture name for static sprite\n * - `string[]`: Array of texture names to load directly\n * - `{ sheet: string; anim: string }`: Reference to a spritesheet animation\n * - `undefined`: Returns empty array\n * @returns Array of PixiJS Texture objects for the animation frames. Returns empty array if:\n * - Definition is undefined\n * - Spritesheet is not found\n * - Animation name doesn't exist in the spritesheet\n * - Animation data is invalid\n *\n * @example\n * Using single texture name:\n * ```typescript\n * const frames = getAnimationFrames('logo_static');\n * const sprite = new Sprite(frames[0]);\n * ```\n *\n * @example\n * Using array of texture names:\n * ```typescript\n * const frames = getAnimationFrames([\n * 'symbol_cherry_0',\n * 'symbol_cherry_1',\n * 'symbol_cherry_2'\n * ]);\n * const sprite = new AnimatedSprite(frames);\n * ```\n *\n * @example\n * Using spritesheet reference:\n * ```typescript\n * const frames = getAnimationFrames({\n * sheet: 'symbols_spritesheet',\n * anim: 'cherry_win'\n * });\n * const sprite = new AnimatedSprite(frames);\n * ```\n *\n * @example\n * Usage in SlotSymbol component:\n * ```typescript\n * private getAnimationTextures(type: string): Texture[] {\n * const key = this.resolveAssetKey(type);\n * const animations = skin?.sources?.animations || {};\n * const def = animations[key] as string[] | { sheet: string; anim: string } | undefined;\n * return getAnimationFrames(def);\n * }\n * ```\n *\n * @public\n */\nexport function getAnimationFrames(\n def: string | string[] | { sheet: string; anim: string } | undefined,\n): Texture[] {\n const names = getAnimationFrameNames(def);\n return names.map((n) => Texture.from(n));\n}\n\n/**\n * Retrieves animation frame names as strings from various definition formats.\n * Similar to getAnimationFrames but returns string[] instead of Texture[].\n * Useful for particle systems that need texture names rather than Texture objects.\n *\n * @param def - Animation definition in one of the supported formats:\n * - `string`: Single texture name\n * - `string[]`: Array of texture names (returned as-is)\n * - `{ sheet: string; anim: string }`: Reference to a spritesheet animation\n * - `undefined`: Returns empty array\n * @returns Array of texture name strings\n *\n * @example\n * ```typescript\n * const frameNames = getAnimationFrameNames({\n * sheet: 'symbols',\n * anim: 'symbols/pic1'\n * });\n * // Returns: ['pic1_0', 'pic1_1', 'pic1_2', ...]\n * ```\n */\nexport function getAnimationFrameNames(\n def: string | string[] | { sheet: string; anim: string } | undefined,\n): string[] {\n if (!def) return [];\n if (typeof def === 'string') return [def];\n if (Array.isArray(def)) return def;\n const sheetRes = Assets.get(def.sheet) as Spritesheet | undefined;\n if (!sheetRes) return [];\n sheetRes.parse?.();\n const nameList: string[] | undefined = sheetRes.data?.animations?.[def.anim];\n if (!nameList || !Array.isArray(nameList)) return [];\n return nameList;\n}\n","import type { EventEmitter } from 'pixi.js';\n\n/**\n * Extract namespace prefix from event names (supports nested namespaces)\n * Example: ExtractNamespace<'hud:spin'> = 'hud'\n * Example: ExtractNamespace<'menu:autoplay:start'> = 'menu:autoplay'\n */\ntype ExtractNamespace<T extends string> = T extends `${infer Prefix}:${infer Rest}`\n ? Rest extends `${string}:${string}`\n ? `${Prefix}:${ExtractNamespace<Rest>}`\n : Prefix\n : never;\n\n/**\n * Get all unique namespaces from event map (supports nested namespaces)\n * Example: GetNamespaces<{'hud:spin': ..., 'menu:autoplay:start': ...}> = 'hud' | 'menu:autoplay'\n */\ntype GetNamespaces<T> = ExtractNamespace<Extract<keyof T, string>>;\n\n/**\n * Filter events by namespace\n * Example: FilterByNamespace<SlotBaseEvents, 'hud'> = { 'hud:spin': () => void, ... }\n */\ntype FilterByNamespace<T, NS extends string> = {\n [K in Extract<keyof T, `${NS}:${string}`>]: T[K];\n};\n\n/**\n * Remove namespace prefix from event names (supports nested namespaces)\n * Example: StripNamespace<'hud:spin', 'hud'> = 'spin'\n * Example: StripNamespace<'menu:autoplay:start', 'menu:autoplay'> = 'start'\n */\ntype StripNamespace<T extends string, NS extends string> = T extends `${NS}:${infer Rest}`\n ? Rest\n : T;\n\n/**\n * Transform event map by removing namespace prefix\n * Example: TransformEventMap<{ 'hud:spin': () => void }, 'hud'> = { 'spin': () => void }\n */\ntype TransformEventMap<T, NS extends string> = {\n [K in Extract<keyof T, string> as StripNamespace<K, NS>]: K extends keyof T ? T[K] : never;\n};\n\n/**\n * Configuration for event bridge\n */\nexport interface EventBridgeConfig {\n /**\n * Namespace prefix to add to forwarded events\n * Example: 'hud' will transform 'spin' to 'hud:spin'\n */\n namespace?: string;\n\n /**\n * Custom transform function for event name and arguments\n * Takes precedence over namespace if provided\n */\n transform?: (event: string, ...args: any[]) => [string, ...any[]];\n\n /**\n * Filter function to selectively forward events\n * Return true to forward, false to skip\n */\n filter?: (event: string) => boolean;\n\n /**\n * Intercept function for side effects before forwarding\n * Useful for UI state changes, logging, etc.\n */\n intercept?: (event: string, ...args: any[]) => void;\n}\n\n/**\n * Event bridge handle for cleanup\n */\nexport interface EventBridgeHandle {\n /**\n * Disconnect the bridge and restore original emit behavior\n */\n disconnect: () => void;\n}\n\n/**\n * Type-safe event bridge configuration\n */\nexport interface TypedEventBridgeConfig<\n TSource extends Record<string, any>,\n TTarget extends Record<string, any>,\n NS extends GetNamespaces<TTarget>,\n> extends Omit<EventBridgeConfig, 'namespace' | 'filter' | 'intercept'> {\n namespace: NS;\n filter?: (event: keyof TSource) => boolean;\n intercept?: <K extends keyof TSource>(event: K, ...args: Parameters<TSource[K]>) => void;\n}\n\n/**\n * Creates an event bridge that automatically forwards all emitted events from source to target.\n * This eliminates the need for manual event binding boilerplate.\n *\n * **Auto-cleanup:** If the source component has a `destroy()` method, the bridge will\n * automatically clean up when the component is destroyed, preventing memory leaks.\n * You can also manually disconnect using the returned handle.\n *\n * @example\n * // Simple namespace forwarding\n * createEventBridge(this.gameHud, this.eventBusPlugin, {\n * namespace: 'hud'\n * });\n * // Now: gameHud.emit('spin') → eventBus.emit('hud:spin')\n * // Auto-cleanup when gameHud.destroy() is called\n *\n * @example\n * // With side effects\n * createEventBridge(this.gameHud, this.eventBusPlugin, {\n * namespace: 'hud',\n * intercept: (event) => {\n * if (event === 'autoplay') this.autoplayMenu.visible = !this.autoplayMenu.visible;\n * }\n * });\n *\n * @example\n * // Manual cleanup (optional)\n * const handle = createEventBridge(this.component, this.eventBus, {\n * transform: (event, ...args) => [`custom:${event}`, ...args]\n * });\n * // Later...\n * handle.disconnect(); // Manual cleanup if needed\n *\n * @param source - The EventEmitter to bridge from\n * @param target - The EventEmitter to forward events to\n * @param config - Bridge configuration options\n * @returns Handle with disconnect method for manual cleanup\n */\nexport function createEventBridge(\n source: EventEmitter,\n target: { emit(event: any, ...args: any[]): boolean },\n config: EventBridgeConfig = {},\n): EventBridgeHandle {\n // Store original methods\n const originalEmit = source.emit.bind(source);\n const originalDestroy = (source as any).destroy?.bind(source);\n\n // Override emit to intercept and forward\n source.emit = function (event: string | symbol, ...args: any[]): boolean {\n // Call original emit first\n const result = originalEmit(event, ...args);\n\n // Only process string events\n if (typeof event !== 'string') {\n return result;\n }\n\n // Apply filter if provided\n if (config.filter && !config.filter(event)) {\n return result;\n }\n\n // Execute intercept for side effects\n if (config.intercept) {\n config.intercept(event, ...args);\n }\n\n // Transform event name and args\n let forwardEvent: string;\n let forwardArgs: any[];\n\n if (config.transform) {\n // Use custom transform\n [forwardEvent, ...forwardArgs] = config.transform(event, ...args);\n } else if (config.namespace) {\n // Use namespace prefix\n forwardEvent = `${config.namespace}:${event}`;\n forwardArgs = args;\n } else {\n // No transformation\n forwardEvent = event;\n forwardArgs = args;\n }\n\n // Forward to target\n target.emit(forwardEvent, ...forwardArgs);\n\n return result;\n };\n\n // Auto-cleanup: Hook into destroy method if it exists\n if (typeof (source as any).destroy === 'function') {\n (source as any).destroy = function (options?: any): void {\n // Restore original emit before destroying\n source.emit = originalEmit;\n\n // Restore original destroy\n if (originalDestroy) {\n (source as any).destroy = originalDestroy;\n }\n\n // Call original destroy\n if (originalDestroy) {\n originalDestroy(options);\n }\n };\n }\n\n // Return cleanup handle for manual disconnect if needed\n return {\n disconnect: () => {\n source.emit = originalEmit;\n if (originalDestroy) {\n (source as any).destroy = originalDestroy;\n }\n },\n };\n}\n\n/**\n * Type-safe event bridge creator\n * Ensures source events match target events after namespace transformation\n *\n * @example\n * // Define source events (without namespace)\n * interface HudEvents {\n * spin: () => void;\n * autoplay: () => void;\n * }\n *\n * // Define target events (with namespace)\n * interface GameEvents {\n * 'hud:spin': () => void;\n * 'hud:autoplay': () => void;\n * 'menu:close': () => void;\n * }\n *\n * // Type-safe bridge - TypeScript validates that HudEvents matches 'hud' namespace in GameEvents\n * createTypedEventBridge<GameEvents, 'hud', HudEvents>(\n * hudComponent,\n * eventBus,\n * { namespace: 'hud' }\n * );\n *\n * @param source - The EventEmitter to bridge from\n * @param target - The EventEmitter to forward events to\n * @param config - Type-safe bridge configuration\n * @returns Handle with disconnect method for manual cleanup\n */\nexport function createTypedEventBridge<\n TTarget extends Record<string, any>,\n NS extends GetNamespaces<TTarget>,\n TSource extends TransformEventMap<FilterByNamespace<TTarget, NS>, NS>,\n>(\n source: EventEmitter,\n target: { emit(event: any, ...args: any[]): boolean },\n config: TypedEventBridgeConfig<TSource, TTarget, NS>,\n): EventBridgeHandle {\n const bridgeConfig: EventBridgeConfig = {\n namespace: config.namespace,\n filter: config.filter as ((event: string) => boolean) | undefined,\n intercept: config.intercept as ((event: string, ...args: any[]) => void) | undefined,\n transform: config.transform,\n };\n\n return createEventBridge(source, target, bridgeConfig);\n}\n","import { mergeWith, isPlainObject } from 'lodash';\n\n/**\n * Sentinel symbol to mark properties for removal during merge.\n * Use this in override objects to explicitly remove a property from the base.\n *\n * @example\n * const base = { a: 1, b: 2 };\n * mergeWithRemove(base, { b: REMOVE }); // → { a: 1 }\n */\nexport const REMOVE = Symbol('REMOVE');\n\n/**\n * Deep merge with support for removing properties using REMOVE symbol.\n * Similar to lodash.merge but:\n * - REMOVE symbol removes the property entirely\n * - Arrays are replaced, not merged\n *\n * @example\n * const base = { a: 1, b: { c: 2, d: 3 } };\n * mergeWithRemove(base, { b: { c: REMOVE } }); // → { a: 1, b: { d: 3 } }\n */\nexport const mergeWithRemove = <T extends object>(base: T, ...overrides: object[]): T => {\n const result = mergeWith({}, base, ...overrides, (_objValue: unknown, srcValue: unknown) => {\n if (srcValue === REMOVE) {\n return REMOVE;\n }\n if (Array.isArray(srcValue)) {\n return srcValue;\n }\n return undefined;\n });\n\n const cleanRemoved = (obj: Record<string, unknown>): Record<string, unknown> => {\n if (!isPlainObject(obj)) return obj;\n for (const key of Object.keys(obj)) {\n if (obj[key] === REMOVE) {\n delete obj[key];\n } else if (isPlainObject(obj[key])) {\n cleanRemoved(obj[key] as Record<string, unknown>);\n }\n }\n return obj;\n };\n\n return cleanRemoved(result) as T;\n};\n\n\n"]}
|
|
1
|
+
{"version":3,"sources":["../../helpers/SVGParser.ts","../../helpers/SVGLoader.ts","../../helpers/SVGAssetHelper.ts","../../helpers/AssetHelper.ts","../../helpers/eventBridge.ts","../../helpers/mergeUtils.ts"],"names":["Assets","Texture"],"mappings":"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","file":"index.js","sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Texture, TextureSource, LoaderParser, ExtensionType, ResolvedAsset } from 'pixi.js';\n// @ts-ignore\nimport { minimatch } from 'minimatch';\n\n/**\n * Style definitions for SVG elements using CSS selectors.\n *\n * Maps CSS selectors to attribute-value pairs that will be applied to matching SVG elements.\n * Commonly used for dynamic theming and color changes.\n *\n * @example\n * ```typescript\n * const styles: SVGStyleData = {\n * '#primary': { fill: '#4CAF50', stroke: '#388E3C' },\n * '.icon': { fill: '#FFFFFF' },\n * 'circle': { opacity: '0.8' }\n * };\n * ```\n *\n * @public\n */\nexport interface SVGStyleData {\n /** CSS selector as key, attributes as value */\n [selector: string]: {\n /** SVG attribute name (e.g., 'fill', 'stroke', 'opacity') */\n [attribute: string]: string;\n };\n}\n\n/**\n * Configuration data for loading and processing SVG files.\n *\n * This interface defines all options available when loading an SVG asset,\n * including styling, sizing, and resolution settings.\n *\n * @example\n * ```typescript\n * const loadData: SVGLoadData = {\n * styles: {\n * '#background': { fill: '#4CAF50' },\n * '#icon': { fill: '#FFFFFF' }\n * },\n * size: { width: 128, height: 128 },\n * resolution: 2\n * };\n * ```\n *\n * @public\n */\nexport interface SVGLoadData {\n /** Style definitions to apply to SVG elements */\n styles?: SVGStyleData;\n /** Target size for rasterization (width and height in pixels) */\n size?: { width: number; height: number };\n /** Resolution multiplier for high-DPI displays (default: 1) */\n resolution?: number;\n /** Button states for multi-state assets (used by SVGAssetHelper) */\n states?: string[];\n}\n\n/**\n * Global configuration for the SVG parser.\n *\n * @public\n */\nexport interface SVGParserConfig {\n /** Glob pattern to match SVG files (uses minimatch) */\n testPattern?: string;\n}\n\n// Parser global configuration\nlet parserConfig: SVGParserConfig = {};\n\n/**\n * Manipulates SVG string by applying styles and size modifications.\n *\n * This function parses the SVG string, applies CSS selector-based styles,\n * and optionally resizes the SVG before returning the modified string.\n *\n * @param svgString - Raw SVG file content as string\n * @param data - Optional load data with styles and size\n * @returns Modified SVG string\n *\n * @internal\n */\nfunction manipulateSVG(svgString: string, data?: SVGLoadData): string {\n const parser = new DOMParser();\n const svgDoc = parser.parseFromString(svgString, 'image/svg+xml');\n const svgElement = svgDoc.documentElement;\n\n // Apply styles\n if (data?.styles) {\n Object.entries(data.styles).forEach(([selector, styles]) => {\n const elements = svgDoc.querySelectorAll(selector);\n elements.forEach((element) => {\n Object.entries(styles).forEach(([attr, value]) => {\n element.setAttribute(attr, value);\n });\n });\n });\n }\n\n // Set size\n if (data?.size) {\n svgElement.setAttribute('width', data.size.width.toString());\n svgElement.setAttribute('height', data.size.height.toString());\n\n // Optionally update the viewBox as well\n // const viewBox = svgElement.getAttribute('viewBox');\n // if (viewBox) {\n // const [x, y] = viewBox.split(' ');\n // svgElement.setAttribute('viewBox', `${x} ${y} ${data.size.width} ${data.size.height}`);\n // }\n }\n\n return new XMLSerializer().serializeToString(svgDoc);\n}\n\n/**\n * Converts an SVG string to a PixiJS Texture by rasterizing it to a canvas.\n *\n * This function creates an Image element from the SVG, draws it to a canvas,\n * and generates a PixiJS Texture from the canvas. Supports resolution scaling\n * for high-DPI displays.\n *\n * @param svgString - SVG content as string\n * @param data - Optional load data with resolution settings\n * @returns Promise that resolves to a PixiJS Texture\n *\n * @internal\n */\nasync function createTextureFromSVG(svgString: string, data?: SVGLoadData): Promise<Texture> {\n const blob = new Blob([svgString], { type: 'image/svg+xml' });\n const url = URL.createObjectURL(blob);\n\n const img = new Image();\n img.src = url;\n\n return new Promise((resolve, reject) => {\n img.onload = () => {\n try {\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n\n if (!ctx) {\n reject(new Error('Could not get canvas context'));\n return;\n }\n\n const resolution = data?.resolution || 1;\n canvas.width = img.width * resolution;\n canvas.height = img.height * resolution;\n\n //ctx.scale(resolution, resolution);\n ctx.drawImage(img, 0, 0);\n\n const source = TextureSource.from(canvas);\n const texture = new Texture(source);\n resolve(texture);\n URL.revokeObjectURL(url);\n } catch (error) {\n reject(error);\n }\n };\n\n img.onerror = () => {\n URL.revokeObjectURL(url);\n reject(new Error('Failed to load SVG image'));\n };\n });\n}\n\n/**\n * PixiJS LoaderParser implementation for SVG files.\n *\n * This parser integrates with PixiJS Assets system to automatically detect,\n * load, and process SVG files as textures. It handles:\n * - SVG file detection via URL pattern matching\n * - Style manipulation using CSS selectors\n * - Size and resolution configuration\n * - Canvas rasterization for texture generation\n *\n * The parser is registered with PixiJS Assets via SVGLoader.install().\n *\n * @remarks\n * This parser uses DOMParser and Canvas API to convert SVG to raster textures.\n * All SVG manipulations happen before rasterization, ensuring clean output.\n *\n * @example\n * ```typescript\n * // Parser is automatically used after SVGLoader.install()\n * await Assets.load({\n * alias: 'icon',\n * src: 'assets/icon.svg',\n * data: {\n * styles: { '#primary': { fill: '#4CAF50' } },\n * size: { width: 64, height: 64 },\n * resolution: 2\n * }\n * });\n * ```\n *\n * @public\n */\nexport const SVGParser: LoaderParser<Texture, SVGLoadData> = {\n /**\n * Extension metadata for the parser.\n *\n * @internal\n */\n extension: {\n type: ExtensionType.LoadParser,\n name: 'svgParser',\n priority: 0,\n },\n\n /**\n * Unique identifier for the parser.\n *\n * @internal\n */\n id: 'svgParser',\n\n /**\n * Tests if a URL should be handled by this parser.\n *\n * By default, matches files ending with .svg extension.\n * Can be customized via configureSVGParser() with a glob pattern.\n *\n * @param url - Asset URL to test\n * @returns True if this parser should handle the URL\n */\n test: (url: string) => {\n // If a custom pattern is provided, use it\n if (parserConfig.testPattern) {\n try {\n const urlObj = new URL(url);\n const pathname = urlObj.pathname.startsWith('/')\n ? urlObj.pathname.slice(1)\n : urlObj.pathname;\n return minimatch(pathname, parserConfig.testPattern, { partial: true });\n } catch {\n // If URL parsing fails, try with the original string\n return minimatch(url, parserConfig.testPattern, { partial: true });\n }\n }\n\n // Default: check that the file actually ends with .svg\n return /\\.svg$/i.test(url);\n },\n\n /**\n * Loads and processes an SVG file into a PixiJS Texture.\n *\n * This method:\n * 1. Fetches the SVG file from the URL\n * 2. Applies style and size manipulations\n * 3. Rasterizes the SVG to a canvas\n * 4. Creates a PixiJS Texture from the canvas\n *\n * @param url - URL of the SVG file to load\n * @param resolvedAsset - Resolved asset with optional load data\n * @returns Promise that resolves to a PixiJS Texture\n */\n async load(url: string, resolvedAsset?: ResolvedAsset<SVGLoadData>): Promise<Texture> {\n // Fetch the SVG file\n const response = await fetch(url);\n const svgString = await response.text();\n\n // Manipulate the SVG\n const manipulatedSVG = manipulateSVG(svgString, resolvedAsset?.data);\n\n // Convert to Texture\n const texture = await createTextureFromSVG(manipulatedSVG, resolvedAsset?.data);\n texture.label = resolvedAsset?.src ?? 'unknown';\n return texture;\n },\n};\n\n/**\n * Configures the SVG parser with global settings.\n *\n * This function allows customization of the parser behavior, such as\n * specifying custom glob patterns for SVG file matching.\n *\n * Typically called by SVGLoader.install() but can be used independently.\n *\n * @param config - Parser configuration options\n *\n * @example\n * ```typescript\n * configureSVGParser({\n * testPattern: 'assets/svg/*.svg'\n * });\n * ```\n *\n * @public\n */\nexport function configureSVGParser(config: SVGParserConfig): void {\n parserConfig = { ...parserConfig, ...config };\n}\n","import { Assets } from 'pixi.js';\nimport { SVGParser, configureSVGParser } from './SVGParser';\n\n/**\n * Configuration options for the SVG loader.\n */\nexport interface SVGLoaderConfig {\n /** Glob pattern to match SVG files (uses minimatch) */\n testPattern?: string;\n}\n\n/**\n * SVG loader plugin for PixiJS Assets system.\n *\n * SVGLoader integrates the SVG parser into PixiJS asset loading pipeline,\n * enabling automatic loading and processing of SVG files as textures.\n *\n * @remarks\n * Install once at application startup using SVGLoader.install().\n * After installation, SVG files can be loaded using PixiJS Assets API or SVGAssetHelper.\n *\n * @public\n */\nexport class SVGLoader {\n private static installed = false;\n\n /**\n * Installs the SVG loader into the PixiJS Assets system.\n *\n * This method must be called once at application startup before loading any SVG assets.\n * It registers the SVG parser with PixiJS, enabling automatic SVG file processing.\n * This method is idempotent - calling it multiple times is safe but only the first call will take effect.\n *\n * @param config - Optional configuration for SVG file matching\n */\n static install(config?: SVGLoaderConfig): void {\n if (this.installed) {\n console.warn('SVGLoader is already installed');\n return;\n }\n\n // Configure parser if options provided\n if (config) {\n configureSVGParser(config);\n }\n\n // Add parser to Assets loader\n Assets.loader.parsers.unshift(SVGParser);\n\n this.installed = true;\n console.log('SVG Loader installed successfully');\n }\n\n /**\n * Checks if the SVG loader has been installed.\n *\n * @returns True if the loader is installed, false otherwise\n */\n static isInstalled(): boolean {\n return this.installed;\n }\n\n /**\n * Uninstalls the SVG loader from the PixiJS Assets system.\n *\n * This method is primarily intended for testing purposes.\n * In production, you typically install the loader once and never uninstall it.\n */\n static uninstall(): void {\n if (!this.installed) {\n return;\n }\n\n // Remove parser from Assets loader\n const index = Assets.loader.parsers.indexOf(SVGParser);\n if (index > -1) {\n Assets.loader.parsers.splice(index, 1);\n }\n\n this.installed = false;\n console.log('SVG Loader uninstalled');\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Assets, Cache, Color, type ColorSource } from 'pixi.js';\nimport { SVGLoadData, SVGStyleData } from './SVGParser';\nimport type { ButtonStateKey } from '../ui/components/ButtonComp';\nimport { lightenColor, darkenColor } from '../utils';\n\n/**\n * Button state styles for SVG assets.\n *\n * Defines the visual appearance of buttons in different interaction states.\n * Each state contains CSS-like style definitions for SVG elements.\n * Uses ButtonComp state names: up, down, over, disabled.\n *\n * @example\n * ```typescript\n * const buttonStyles: ButtonState = {\n * up: { '#primary': { fill: '#4CAF50' } },\n * over: { '#primary': { fill: '#66BB6A' } },\n * down: { '#primary': { fill: '#388E3C' } },\n * disabled: { '#primary': { fill: '#CCCCCC' } }\n * };\n * ```\n */\nexport interface ButtonState {\n /** Up/default state styles */\n up: SVGStyleData;\n /** Over/hover state styles */\n over: SVGStyleData;\n /** Down/pressed state styles */\n down: SVGStyleData;\n /** Disabled state styles (optional) */\n disabled?: SVGStyleData;\n /** Selected up state styles */\n selected_up?: SVGStyleData;\n /** Selected over state styles */\n selected_over?: SVGStyleData;\n /** Selected down state styles */\n selected_down?: SVGStyleData;\n /** Selected disabled state styles */\n selected_disabled?: SVGStyleData;\n}\n\n/**\n * Configuration for loading SVG assets.\n *\n * @example\n * ```typescript\n * const config: SVGAssetConfig = {\n * alias: 'play_button',\n * src: 'assets/svg/buttons/play.svg',\n * size: { width: 120, height: 120 },\n * resolution: 2,\n * themeColor: '#4CAF50',\n * states: ['up', 'over', 'down']\n * };\n * ```\n */\nexport interface SVGAssetConfig {\n /** Unique identifier for the asset */\n alias: string;\n /** Path to the SVG file */\n src: string;\n /** Target size for rasterization */\n size?: { width: number; height: number };\n /** Resolution multiplier for high-DPI displays */\n resolution?: number;\n /** Theme color for styling (supports all PixiJS ColorSource formats) */\n themeColor?: ColorSource;\n /** Button states to generate (e.g., ['up', 'over', 'down', 'disabled']) */\n states?: ButtonStateKey[];\n}\n\n/**\n * High-level utility for loading and managing SVG assets in PixiJS.\n *\n * SVGAssetHelper provides a convenient API for loading SVG files as PixiJS textures\n * with automatic theming, button state management, and batch loading capabilities.\n *\n * ## Features\n *\n * - **Theme Support**: Global and per-asset theme colors\n * - **Button States**: Automatic generation of up, over, down, disabled states\n * - **Batch Loading**: Load multiple assets efficiently\n * - **Color Manipulation**: Automatic lighten/darken for button states\n * - **Cache Management**: Check and clear loaded assets\n * - **Custom Styles**: Create custom style configurations\n *\n * ## Workflow\n *\n * 1. **Initialize**: Set global theme color (optional)\n * 2. **Load**: Load SVG assets with configuration\n * 3. **Use**: Retrieve textures and create sprites\n * 4. **Manage**: Check cache and clear unused assets\n *\n * @example\n * ```typescript\n * import { SVGAssetHelper, SVGLoader } from '@rb-games/core/helpers';\n * import { Sprite } from 'pixi.js';\n *\n * // Initialize SVG system\n * SVGLoader.install();\n * SVGAssetHelper.setThemeColor('#4CAF50');\n *\n * // Load a simple icon\n * await SVGAssetHelper.loadSVGAsset({\n * alias: 'settings_icon',\n * src: 'assets/svg/settings.svg',\n * size: { width: 48, height: 48 },\n * themeColor: '#2196F3'\n * });\n *\n * // Create sprite\n * const icon = new Sprite(SVGAssetHelper.getAsset('settings_icon'));\n * ```\n *\n * @example\n * ```typescript\n * // Load button with states\n * await SVGAssetHelper.loadButtonAsset({\n * alias: 'play_btn',\n * src: 'assets/svg/play.svg',\n * size: { width: 120, height: 120 },\n * themeColor: '#4CAF50',\n * states: ['up', 'over', 'down']\n * });\n *\n * // Create interactive button\n * const button = new Sprite(SVGAssetHelper.getAsset('play_btn', 'up'));\n * button.eventMode = 'static';\n * button.cursor = 'pointer';\n *\n * button.on('pointerover', () => {\n * button.texture = SVGAssetHelper.getAsset('play_btn', 'over');\n * });\n *\n * button.on('pointerout', () => {\n * button.texture = SVGAssetHelper.getAsset('play_btn', 'up');\n * });\n * ```\n *\n * @example\n * ```typescript\n * // Batch load multiple assets\n * await SVGAssetHelper.loadBatchAssets([\n * {\n * alias: 'star_icon',\n * src: 'assets/svg/icons/star.svg',\n * size: { width: 32, height: 32 },\n * themeColor: '#FFD700'\n * },\n * {\n * alias: 'close_btn',\n * src: 'assets/svg/buttons/close.svg',\n * size: { width: 40, height: 40 },\n * states: ['up', 'over'],\n * themeColor: '#F44336'\n * }\n * ]);\n * ```\n *\n * @public\n */\nexport class SVGAssetHelper {\n private static themeColor: ColorSource = '#4CAF50';\n\n /**\n * Sets the global theme color for all SVG assets.\n *\n * This color will be used as the default for all assets unless overridden\n * in individual asset configurations.\n *\n * @param color - Theme color (supports all PixiJS ColorSource formats)\n *\n * @example\n * ```typescript\n * // Set theme with hex string\n * SVGAssetHelper.setThemeColor('#4CAF50');\n *\n * // Set theme with number\n * SVGAssetHelper.setThemeColor(0x4CAF50);\n *\n * // Set theme with RGB array\n * SVGAssetHelper.setThemeColor([0.3, 0.69, 0.31]);\n * ```\n */\n static setThemeColor(color: ColorSource): void {\n this.themeColor = color;\n }\n\n /**\n * Gets the current global theme color.\n *\n * @returns The current theme color as ColorSource\n *\n * @example\n * ```typescript\n * const currentTheme = SVGAssetHelper.getThemeColor();\n * // Can be used directly or converted as needed\n * const hex = new Color(currentTheme).toHex();\n * ```\n */\n static getThemeColor(): ColorSource {\n return this.themeColor;\n }\n\n /**\n * Create button state styles based on theme color\n */\n static createButtonStyles(\n themeColor?: ColorSource,\n variations?: { /** lighten amount */ over: number; /** darken amount */ down: number },\n ): ButtonState {\n const baseColor = themeColor || this.themeColor;\n const baseColorHex = new Color(baseColor).toHex();\n\n return {\n up: {\n '#primary': { fill: baseColorHex },\n '#secondary': { fill: '#ffffff' },\n '#background': { fill: baseColorHex },\n },\n over: {\n '#primary': { fill: lightenColor(baseColor, variations?.over || 0.15).toHex() },\n '#secondary': { fill: '#ffffff' },\n '#background': { fill: lightenColor(baseColor, variations?.over || 0.15).toHex() },\n },\n down: {\n '#primary': { fill: darkenColor(baseColor, variations?.down || 0.15).toHex() },\n '#secondary': { fill: '#ffffff' },\n '#background': { fill: darkenColor(baseColor, variations?.down || 0.15).toHex() },\n },\n disabled: {\n '#primary': { fill: '#cccccc' },\n '#secondary': { fill: '#999999' },\n '#background': { fill: '#cccccc' },\n },\n selected_up: {\n '#primary': { fill: baseColorHex },\n '#secondary': { fill: '#ffffff' },\n '#background': { fill: baseColorHex },\n },\n selected_over: {\n '#primary': { fill: lightenColor(baseColor, variations?.over || 0.15).toHex() },\n '#secondary': { fill: '#ffffff' },\n '#background': { fill: lightenColor(baseColor, variations?.over || 0.15).toHex() },\n },\n selected_down: {\n '#primary': { fill: darkenColor(baseColor, variations?.down || 0.15).toHex() },\n '#secondary': { fill: '#ffffff' },\n '#background': { fill: darkenColor(baseColor, variations?.down || 0.15).toHex() },\n },\n selected_disabled: {\n '#primary': { fill: '#cccccc' },\n '#secondary': { fill: '#999999' },\n '#background': { fill: '#cccccc' },\n },\n };\n }\n\n /**\n * Create custom styles\n */\n static createCustomStyles(config: {\n selectors: string[];\n colors: { [state: string]: string[] };\n }): { [state: string]: SVGStyleData } {\n const result: { [state: string]: SVGStyleData } = {};\n\n Object.entries(config.colors).forEach(([state, colors]) => {\n result[state] = {};\n config.selectors.forEach((selector, index) => {\n if (colors[index]) {\n result[state][selector] = { fill: colors[index] };\n }\n });\n });\n\n return result;\n }\n\n /**\n * Loads a single SVG asset as a PixiJS texture.\n *\n * This method loads an SVG file, applies optional theme colors and styles,\n * and registers it with the PixiJS Assets system for later retrieval.\n *\n * @param config - Asset configuration\n * @returns Promise that resolves when the asset is loaded\n *\n * @example\n * ```typescript\n * // Load a simple icon\n * await SVGAssetHelper.loadSVGAsset({\n * alias: 'home_icon',\n * src: 'assets/svg/home.svg',\n * size: { width: 64, height: 64 },\n * resolution: 2\n * });\n *\n * // Load with theme color\n * await SVGAssetHelper.loadSVGAsset({\n * alias: 'settings_icon',\n * src: 'assets/svg/settings.svg',\n * size: { width: 48, height: 48 },\n * themeColor: '#2196F3'\n * });\n * ```\n */\n static async loadSVGAsset(config: SVGAssetConfig): Promise<void> {\n const loadData: SVGLoadData = {\n size: config.size,\n resolution: config.resolution || 1,\n };\n\n if (config.themeColor) {\n const styles = this.createButtonStyles(config.themeColor);\n loadData.styles = styles.up;\n }\n\n await Assets.load({\n alias: config.alias,\n src: `${config.src}`,\n data: loadData,\n });\n }\n\n /**\n * Loads a button SVG asset with multiple interaction states.\n *\n * Automatically generates up, over, down, and optionally disabled states\n * by applying color variations (lighten for over, darken for down).\n * Each state is loaded as a separate texture with the naming convention `{alias}_{state}`.\n *\n * @param config - Button asset configuration\n * @returns Promise that resolves when all button states are loaded\n *\n * @example\n * ```typescript\n * // Load button with default states\n * await SVGAssetHelper.loadButtonAsset({\n * alias: 'play_btn',\n * src: 'assets/svg/play.svg',\n * size: { width: 120, height: 120 },\n * themeColor: '#4CAF50'\n * });\n *\n * // Access different states\n * const upTexture = SVGAssetHelper.getAsset('play_btn', 'up');\n * const overTexture = SVGAssetHelper.getAsset('play_btn', 'over');\n * const downTexture = SVGAssetHelper.getAsset('play_btn', 'down');\n * ```\n *\n * @example\n * ```typescript\n * // Custom states\n * await SVGAssetHelper.loadButtonAsset({\n * alias: 'custom_btn',\n * src: 'assets/svg/button.svg',\n * size: { width: 100, height: 40 },\n * themeColor: '#E91E63',\n * states: ['up', 'over', 'down', 'disabled']\n * });\n * ```\n */\n static async loadButtonAsset(config: SVGAssetConfig): Promise<void> {\n const styles = this.createButtonStyles(\n config.themeColor\n ? typeof config.themeColor === 'number'\n ? new Color(config.themeColor).toHex()\n : config.themeColor\n : undefined,\n );\n\n const states = config.states || ['up', 'over', 'down'];\n\n for (const state of states) {\n const stateStyles = styles[state as keyof ButtonState];\n if (stateStyles) {\n const loadData: SVGLoadData = {\n styles: stateStyles,\n size: config.size,\n resolution: config.resolution || 1,\n };\n\n const hash = await this.generateAssetHash(config.src, loadData);\n\n await Assets.load({\n alias: `${config.alias}_${state}`,\n src: `${config.src}?hash=${hash}`,\n data: loadData,\n });\n }\n }\n }\n\n /**\n * Loads multiple SVG assets in parallel for efficient batch loading.\n *\n * Automatically determines whether to load each asset as a simple SVG or\n * as a button with states based on the states property.\n *\n * @param basePath - Base directory path for all assets (assets without src will use basePath/alias.svg)\n * @param assets - Array of asset configurations (strings, objects, or mixed)\n * @param defaults - Optional default configuration applied to all assets\n * @returns Promise that resolves when all assets are loaded\n *\n * @example\n * ```typescript\n * // Simple string array (most convenient)\n * await SVGAssetHelper.loadBatchAssets(\n * 'assets/svg/desktop',\n * ['btn_bet_minus', 'btn_bet_plus', 'btn_spin'],\n * {\n * size: { width: 100, height: 100 },\n * states: ['up', 'over', 'down', 'disabled']\n * }\n * );\n *\n * // Mixed array (strings and objects for customization)\n * await SVGAssetHelper.loadBatchAssets(\n * 'assets/svg/desktop',\n * [\n * 'btn_bet_minus', // uses default size\n * 'btn_bet_plus', // uses default size\n * { alias: 'btn_spin', size: { width: 120, height: 120 } } // custom size\n * ],\n * {\n * size: { width: 80, height: 80 },\n * states: ['up', 'over', 'down', 'disabled']\n * }\n * );\n *\n * // All objects (full customization)\n * await SVGAssetHelper.loadBatchAssets(\n * 'assets/svg/desktop',\n * [\n * { alias: 'btn_bet_minus', size: { width: 90, height: 90 } },\n * { alias: 'btn_bet_plus' }, // uses default size\n * { alias: 'btn_spin', states: ['up', 'over'] } // custom states\n * ],\n * {\n * size: { width: 100, height: 100 },\n * states: ['up', 'over', 'down', 'disabled']\n * }\n * );\n *\n * // With full src paths (when assets are in different directories)\n * await SVGAssetHelper.loadBatchAssets(\n * '',\n * [\n * {\n * alias: 'star_icon',\n * src: 'assets/svg/icons/star.svg',\n * size: { width: 32, height: 32 },\n * themeColor: '#FFD700'\n * },\n * {\n * alias: 'close_btn',\n * src: 'assets/svg/buttons/close.svg',\n * size: { width: 40, height: 40 },\n * states: ['up', 'over'],\n * themeColor: '#F44336'\n * }\n * ]\n * );\n * ```\n */\n static async loadBatchAssets(\n basePath: string,\n assets: Array<string | Partial<SVGAssetConfig>>,\n defaults?: Partial<SVGAssetConfig>,\n ): Promise<void> {\n const defaultConfig = defaults || {};\n\n // Convert string array to asset configs\n const assetConfigs: Array<Partial<SVGAssetConfig>> = assets.map((asset) =>\n typeof asset === 'string' ? { alias: asset } : asset,\n );\n\n const configs: SVGAssetConfig[] = assetConfigs.map((asset) => ({\n alias: asset.alias!,\n src: asset.src || (basePath ? `${basePath}/${asset.alias}.svg` : asset.alias!),\n size: asset.size || defaultConfig.size,\n states: asset.states || defaultConfig.states,\n themeColor: asset.themeColor || defaultConfig.themeColor,\n resolution: asset.resolution || defaultConfig.resolution,\n })) as SVGAssetConfig[];\n\n const promises = configs.map((config) => {\n if (config.states && config.states.length > 1) {\n return this.loadButtonAsset(config);\n } else {\n return this.loadSVGAsset(config);\n }\n });\n\n await Promise.all(promises);\n }\n\n /**\n * Retrieves a loaded SVG asset texture.\n *\n * For button assets with states, specify the state parameter to get\n * the specific state texture.\n *\n * @param alias - Asset alias used during loading\n * @param state - Button state (for button assets)\n * @returns The PixiJS texture\n *\n * @example\n * ```typescript\n * // Get simple asset\n * const iconTexture = SVGAssetHelper.getAsset('home_icon');\n * const sprite = new Sprite(iconTexture);\n *\n * // Get button state\n * const upTexture = SVGAssetHelper.getAsset('play_btn', 'up');\n * const overTexture = SVGAssetHelper.getAsset('play_btn', 'over');\n * ```\n */\n static getAsset(alias: string, state?: string): any {\n const fullAlias = state ? `${alias}_${state}` : alias;\n return Assets.get(fullAlias);\n }\n\n /**\n * Check if asset exists in cache\n */\n static hasAsset(alias: string, state?: string): boolean {\n const fullAlias = state ? `${alias}_${state}` : alias;\n return Cache.has(fullAlias);\n }\n\n /**\n * Clear specific asset from cache\n */\n static clearAsset(alias: string, state?: string): void {\n const fullAlias = state ? `${alias}_${state}` : alias;\n if (Cache.has(fullAlias)) {\n Cache.remove(fullAlias);\n }\n }\n\n /**\n * Generate SHA-256 hash for asset configuration.\n * This creates a unique identifier based on the actual asset properties (src, styles, size, resolution)\n * rather than the state name, enabling efficient cache reuse when multiple states have identical configurations.\n *\n * @param src - Source path of the SVG\n * @param data - Load data containing styles, size, and resolution\n * @returns SHA-256 hash string\n */\n private static async generateAssetHash(src: string, data: SVGLoadData): Promise<string> {\n const configString = JSON.stringify({\n src,\n styles: data.styles || {},\n size: data.size || {},\n resolution: data.resolution || 1,\n });\n\n const encoder = new TextEncoder();\n const dataBuffer = encoder.encode(configString);\n const hashBuffer = await crypto.subtle.digest('SHA-256', dataBuffer);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n const hashHex = hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');\n\n return hashHex.substring(0, 12);\n }\n}\n","import { Assets, Spritesheet, Texture } from 'pixi.js';\nimport type { ButtonCompSkinData, ButtonStateKey } from '../ui/components';\n\n/**\n * Generates ButtonComp skin data from asset alias and states.\n *\n * Uses ButtonComp state keys directly (up, over, down, disabled) without any mapping.\n * Creates texture references for each state with the naming convention `{alias}_{state}`.\n *\n * @param alias - Asset alias used in texture names (e.g., 'btn_bet_minus')\n * @param states - Array of ButtonComp state names (default: ['up', 'over', 'down', 'disabled'])\n * @returns ButtonComp skin data with texture references for each state\n *\n * @example\n * ```typescript\n * // Generate skin for a button with all states\n * const decreaseButtonSkin = generateButtonSkinFromAsset('btn_bet_minus');\n * // Result: { up: { background: { texture: 'btn_bet_minus_up' } }, over: ..., down: ..., disabled: ... }\n *\n * // Generate skin for a button with custom states (only up and over)\n * const playButtonSkin = generateButtonSkinFromAsset('btn_play', undefined, ['up', 'over']);\n * // Result: { up: { background: { texture: 'btn_play_up' } }, over: { background: { texture: 'btn_play_over' } } }\n * ```\n */\nexport function generateButtonSkinFromAsset(\n backgroundName: string,\n iconName?: string,\n buttonStates: ButtonStateKey[] = ['up', 'over', 'down', 'disabled'],\n iconStates?: ButtonStateKey[],\n): ButtonCompSkinData {\n const skinData: Record<string, any> = {};\n\n // Background\n buttonStates.forEach((state) => {\n skinData[state] = {\n ...(skinData[state] ?? {}),\n background: { texture: `${backgroundName}_${state}` },\n };\n });\n\n // Icon (optional)\n if (iconName) {\n if (iconStates === undefined) {\n // Non-variant icon: apply to the same states we generated for the background\n buttonStates.forEach((state) => {\n skinData[state] = {\n ...(skinData[state] ?? {}),\n icon: { texture: iconName },\n };\n });\n } else {\n // Variant icon: only for provided icon states\n iconStates.forEach((state) => {\n skinData[state] = {\n ...(skinData[state] ?? {}),\n icon: { texture: `${iconName}_${state}` },\n };\n });\n }\n }\n\n return skinData as ButtonCompSkinData;\n}\n\n/**\n * Retrieves animation frames as PixiJS textures from various definition formats.\n *\n * This helper function supports three input formats:\n * 1. **Single texture name**: String identifier for a static sprite\n * 2. **Array of texture names**: Direct list of texture identifiers for animation\n * 3. **Spritesheet reference**: Object with `sheet` (spritesheet asset name) and `anim` (animation name)\n *\n * The function handles spritesheet parsing automatically and safely returns an empty array\n * if the definition is invalid or assets are not found.\n *\n * @param def - Animation definition in one of the supported formats:\n * - `string`: Single texture name for static sprite\n * - `string[]`: Array of texture names to load directly\n * - `{ sheet: string; anim: string }`: Reference to a spritesheet animation\n * - `undefined`: Returns empty array\n * @returns Array of PixiJS Texture objects for the animation frames. Returns empty array if:\n * - Definition is undefined\n * - Spritesheet is not found\n * - Animation name doesn't exist in the spritesheet\n * - Animation data is invalid\n *\n * @example\n * Using single texture name:\n * ```typescript\n * const frames = getAnimationFrames('logo_static');\n * const sprite = new Sprite(frames[0]);\n * ```\n *\n * @example\n * Using array of texture names:\n * ```typescript\n * const frames = getAnimationFrames([\n * 'symbol_cherry_0',\n * 'symbol_cherry_1',\n * 'symbol_cherry_2'\n * ]);\n * const sprite = new AnimatedSprite(frames);\n * ```\n *\n * @example\n * Using spritesheet reference:\n * ```typescript\n * const frames = getAnimationFrames({\n * sheet: 'symbols_spritesheet',\n * anim: 'cherry_win'\n * });\n * const sprite = new AnimatedSprite(frames);\n * ```\n *\n * @example\n * Usage in SlotSymbol component:\n * ```typescript\n * private getAnimationTextures(type: string): Texture[] {\n * const key = this.resolveAssetKey(type);\n * const animations = skin?.sources?.animations || {};\n * const def = animations[key] as string[] | { sheet: string; anim: string } | undefined;\n * return getAnimationFrames(def);\n * }\n * ```\n *\n * @public\n */\nexport function getAnimationFrames(\n def: string | string[] | { sheet: string; anim: string } | undefined,\n): Texture[] {\n const names = getAnimationFrameNames(def);\n return names.map((n) => Texture.from(n));\n}\n\n/**\n * Retrieves animation frame names as strings from various definition formats.\n * Similar to getAnimationFrames but returns string[] instead of Texture[].\n * Useful for particle systems that need texture names rather than Texture objects.\n *\n * @param def - Animation definition in one of the supported formats:\n * - `string`: Single texture name\n * - `string[]`: Array of texture names (returned as-is)\n * - `{ sheet: string; anim: string }`: Reference to a spritesheet animation\n * - `undefined`: Returns empty array\n * @returns Array of texture name strings\n *\n * @example\n * ```typescript\n * const frameNames = getAnimationFrameNames({\n * sheet: 'symbols',\n * anim: 'symbols/pic1'\n * });\n * // Returns: ['pic1_0', 'pic1_1', 'pic1_2', ...]\n * ```\n */\nexport function getAnimationFrameNames(\n def: string | string[] | { sheet: string; anim: string } | undefined,\n): string[] {\n if (!def) return [];\n if (typeof def === 'string') return [def];\n if (Array.isArray(def)) return def;\n const sheetRes = Assets.get(def.sheet) as Spritesheet | undefined;\n if (!sheetRes) return [];\n sheetRes.parse?.();\n const nameList: string[] | undefined = sheetRes.data?.animations?.[def.anim];\n if (!nameList || !Array.isArray(nameList)) return [];\n return nameList;\n}\n","import type { EventEmitter } from 'pixi.js';\n\n/**\n * Extract namespace prefix from event names (supports nested namespaces)\n * Example: ExtractNamespace<'hud:spin'> = 'hud'\n * Example: ExtractNamespace<'menu:autoplay:start'> = 'menu:autoplay'\n */\ntype ExtractNamespace<T extends string> = T extends `${infer Prefix}:${infer Rest}`\n ? Rest extends `${string}:${string}`\n ? `${Prefix}:${ExtractNamespace<Rest>}`\n : Prefix\n : never;\n\n/**\n * Get all unique namespaces from event map (supports nested namespaces)\n * Example: GetNamespaces<{'hud:spin': ..., 'menu:autoplay:start': ...}> = 'hud' | 'menu:autoplay'\n */\ntype GetNamespaces<T> = ExtractNamespace<Extract<keyof T, string>>;\n\n/**\n * Filter events by namespace\n * Example: FilterByNamespace<SlotBaseEvents, 'hud'> = { 'hud:spin': () => void, ... }\n */\ntype FilterByNamespace<T, NS extends string> = {\n [K in Extract<keyof T, `${NS}:${string}`>]: T[K];\n};\n\n/**\n * Remove namespace prefix from event names (supports nested namespaces)\n * Example: StripNamespace<'hud:spin', 'hud'> = 'spin'\n * Example: StripNamespace<'menu:autoplay:start', 'menu:autoplay'> = 'start'\n */\ntype StripNamespace<T extends string, NS extends string> = T extends `${NS}:${infer Rest}`\n ? Rest\n : T;\n\n/**\n * Transform event map by removing namespace prefix\n * Example: TransformEventMap<{ 'hud:spin': () => void }, 'hud'> = { 'spin': () => void }\n */\ntype TransformEventMap<T, NS extends string> = {\n [K in Extract<keyof T, string> as StripNamespace<K, NS>]: K extends keyof T ? T[K] : never;\n};\n\n/**\n * Configuration for event bridge\n */\nexport interface EventBridgeConfig {\n /**\n * Namespace prefix to add to forwarded events\n * Example: 'hud' will transform 'spin' to 'hud:spin'\n */\n namespace?: string;\n\n /**\n * Custom transform function for event name and arguments\n * Takes precedence over namespace if provided\n */\n transform?: (event: string, ...args: any[]) => [string, ...any[]];\n\n /**\n * Filter function to selectively forward events\n * Return true to forward, false to skip\n */\n filter?: (event: string) => boolean;\n\n /**\n * Intercept function for side effects before forwarding\n * Useful for UI state changes, logging, etc.\n */\n intercept?: (event: string, ...args: any[]) => void;\n}\n\n/**\n * Event bridge handle for cleanup\n */\nexport interface EventBridgeHandle {\n /**\n * Disconnect the bridge and restore original emit behavior\n */\n disconnect: () => void;\n}\n\n/**\n * Type-safe event bridge configuration\n */\nexport interface TypedEventBridgeConfig<\n TSource extends Record<string, any>,\n TTarget extends Record<string, any>,\n NS extends GetNamespaces<TTarget>,\n> extends Omit<EventBridgeConfig, 'namespace' | 'filter' | 'intercept'> {\n namespace: NS;\n filter?: (event: keyof TSource) => boolean;\n intercept?: <K extends keyof TSource>(event: K, ...args: Parameters<TSource[K]>) => void;\n}\n\n/**\n * Creates an event bridge that automatically forwards all emitted events from source to target.\n * This eliminates the need for manual event binding boilerplate.\n *\n * **Auto-cleanup:** If the source component has a `destroy()` method, the bridge will\n * automatically clean up when the component is destroyed, preventing memory leaks.\n * You can also manually disconnect using the returned handle.\n *\n * @example\n * // Simple namespace forwarding\n * createEventBridge(this.gameHud, this.eventBusPlugin, {\n * namespace: 'hud'\n * });\n * // Now: gameHud.emit('spin') → eventBus.emit('hud:spin')\n * // Auto-cleanup when gameHud.destroy() is called\n *\n * @example\n * // With side effects\n * createEventBridge(this.gameHud, this.eventBusPlugin, {\n * namespace: 'hud',\n * intercept: (event) => {\n * if (event === 'autoplay') this.autoplayMenu.visible = !this.autoplayMenu.visible;\n * }\n * });\n *\n * @example\n * // Manual cleanup (optional)\n * const handle = createEventBridge(this.component, this.eventBus, {\n * transform: (event, ...args) => [`custom:${event}`, ...args]\n * });\n * // Later...\n * handle.disconnect(); // Manual cleanup if needed\n *\n * @param source - The EventEmitter to bridge from\n * @param target - The EventEmitter to forward events to\n * @param config - Bridge configuration options\n * @returns Handle with disconnect method for manual cleanup\n */\nexport function createEventBridge(\n source: EventEmitter,\n target: { emit(event: any, ...args: any[]): boolean },\n config: EventBridgeConfig = {},\n): EventBridgeHandle {\n // Store original methods\n const originalEmit = source.emit.bind(source);\n const originalDestroy = (source as any).destroy?.bind(source);\n\n // Override emit to intercept and forward\n source.emit = function (event: string | symbol, ...args: any[]): boolean {\n // Call original emit first\n const result = originalEmit(event, ...args);\n\n // Only process string events\n if (typeof event !== 'string') {\n return result;\n }\n\n // Apply filter if provided\n if (config.filter && !config.filter(event)) {\n return result;\n }\n\n // Execute intercept for side effects\n if (config.intercept) {\n config.intercept(event, ...args);\n }\n\n // Transform event name and args\n let forwardEvent: string;\n let forwardArgs: any[];\n\n if (config.transform) {\n // Use custom transform\n [forwardEvent, ...forwardArgs] = config.transform(event, ...args);\n } else if (config.namespace) {\n // Use namespace prefix\n forwardEvent = `${config.namespace}:${event}`;\n forwardArgs = args;\n } else {\n // No transformation\n forwardEvent = event;\n forwardArgs = args;\n }\n\n // Forward to target\n target.emit(forwardEvent, ...forwardArgs);\n\n return result;\n };\n\n // Auto-cleanup: Hook into destroy method if it exists\n if (typeof (source as any).destroy === 'function') {\n (source as any).destroy = function (options?: any): void {\n // Restore original emit before destroying\n source.emit = originalEmit;\n\n // Restore original destroy\n if (originalDestroy) {\n (source as any).destroy = originalDestroy;\n }\n\n // Call original destroy\n if (originalDestroy) {\n originalDestroy(options);\n }\n };\n }\n\n // Return cleanup handle for manual disconnect if needed\n return {\n disconnect: () => {\n source.emit = originalEmit;\n if (originalDestroy) {\n (source as any).destroy = originalDestroy;\n }\n },\n };\n}\n\n/**\n * Type-safe event bridge creator\n * Ensures source events match target events after namespace transformation\n *\n * @example\n * // Define source events (without namespace)\n * interface HudEvents {\n * spin: () => void;\n * autoplay: () => void;\n * }\n *\n * // Define target events (with namespace)\n * interface GameEvents {\n * 'hud:spin': () => void;\n * 'hud:autoplay': () => void;\n * 'menu:close': () => void;\n * }\n *\n * // Type-safe bridge - TypeScript validates that HudEvents matches 'hud' namespace in GameEvents\n * createTypedEventBridge<GameEvents, 'hud', HudEvents>(\n * hudComponent,\n * eventBus,\n * { namespace: 'hud' }\n * );\n *\n * @param source - The EventEmitter to bridge from\n * @param target - The EventEmitter to forward events to\n * @param config - Type-safe bridge configuration\n * @returns Handle with disconnect method for manual cleanup\n */\nexport function createTypedEventBridge<\n TTarget extends Record<string, any>,\n NS extends GetNamespaces<TTarget>,\n TSource extends TransformEventMap<FilterByNamespace<TTarget, NS>, NS>,\n>(\n source: EventEmitter,\n target: { emit(event: any, ...args: any[]): boolean },\n config: TypedEventBridgeConfig<TSource, TTarget, NS>,\n): EventBridgeHandle {\n const bridgeConfig: EventBridgeConfig = {\n namespace: config.namespace,\n filter: config.filter as ((event: string) => boolean) | undefined,\n intercept: config.intercept as ((event: string, ...args: any[]) => void) | undefined,\n transform: config.transform,\n };\n\n return createEventBridge(source, target, bridgeConfig);\n}\n","import { mergeWith, isPlainObject } from 'lodash';\n\n/**\n * Sentinel symbol to mark properties for removal during merge.\n * Use this in override objects to explicitly remove a property from the base.\n *\n * @example\n * const base = { a: 1, b: 2 };\n * mergeWithRemove(base, { b: REMOVE }); // → { a: 1 }\n */\nexport const REMOVE = Symbol('REMOVE');\n\n/**\n * Deep merge with support for removing properties using REMOVE symbol.\n * Similar to lodash.merge but:\n * - REMOVE symbol removes the property entirely\n * - Arrays are replaced, not merged\n *\n * @example\n * const base = { a: 1, b: { c: 2, d: 3 } };\n * mergeWithRemove(base, { b: { c: REMOVE } }); // → { a: 1, b: { d: 3 } }\n */\nexport const mergeWithRemove = <T extends object>(base: T, ...overrides: object[]): T => {\n const result = mergeWith({}, base, ...overrides, (_objValue: unknown, srcValue: unknown) => {\n if (srcValue === REMOVE) {\n return REMOVE;\n }\n if (Array.isArray(srcValue)) {\n return srcValue;\n }\n return undefined;\n });\n\n const cleanRemoved = (obj: Record<string, unknown>): Record<string, unknown> => {\n if (!isPlainObject(obj)) return obj;\n for (const key of Object.keys(obj)) {\n if (obj[key] === REMOVE) {\n delete obj[key];\n } else if (isPlainObject(obj[key])) {\n cleanRemoved(obj[key] as Record<string, unknown>);\n }\n }\n return obj;\n };\n\n return cleanRemoved(result) as T;\n};\n\n\n"]}
|
package/dist/i18n/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { changeLanguage, getCurrentLanguage, getI18nInstance, initSlotI18n, isI18nReady, onLanguageChanged, resolveLanguageFromUrl, t } from '../chunk-
|
|
1
|
+
export { changeLanguage, getCurrentLanguage, getI18nInstance, initSlotI18n, isI18nReady, onLanguageChanged, resolveLanguageFromUrl, t } from '../chunk-P4GCINNA.js';
|
|
2
2
|
import '../chunk-NQMORMNP.js';
|
|
3
|
-
import '../chunk-
|
|
3
|
+
import '../chunk-C45KDREE.js';
|
|
4
4
|
import '../chunk-G3PMV62Z.js';
|
|
5
5
|
//# sourceMappingURL=index.js.map
|
|
6
6
|
//# sourceMappingURL=index.js.map
|