{"version":3,"file":"spritesheetAsset.mjs","sources":["../src/spritesheetAsset.ts"],"sourcesContent":["import { copySearchParams, LoaderParserPriority } from '@pixi/assets';\nimport { extensions, ExtensionType, settings, utils } from '@pixi/core';\nimport { Spritesheet } from './Spritesheet';\n\nimport type { AssetExtension, Loader, ResolvedAsset, UnresolvedAsset } from '@pixi/assets';\nimport type { Texture } from '@pixi/core';\nimport type { ISpritesheetData } from './Spritesheet';\n\nexport interface SpriteSheetJson extends ISpritesheetData\n{\n    meta: {\n        image: string;\n        scale: string;\n        // eslint-disable-next-line camelcase\n        related_multi_packs?: string[];\n    };\n}\n\nconst validImages = ['jpg', 'png', 'jpeg', 'avif', 'webp',\n    's3tc', 's3tc_sRGB', 'etc', 'etc1', 'pvrtc', 'atc', 'astc', 'bptc'];\n\nfunction getCacheableAssets(keys: string[], asset: Spritesheet, ignoreMultiPack: boolean)\n{\n    const out: Record<string, Texture | Spritesheet> = {};\n\n    keys.forEach((key: string) =>\n    {\n        out[key] = asset;\n    });\n\n    Object.keys(asset.textures).forEach((key) =>\n    {\n        out[`${asset.cachePrefix}${key}`] = asset.textures[key];\n    });\n\n    if (!ignoreMultiPack)\n    {\n        const basePath = utils.path.dirname(keys[0]);\n\n        asset.linkedSheets.forEach((item: Spritesheet, i) =>\n        {\n            Object.assign(out, getCacheableAssets(\n                [`${basePath}/${asset.data.meta.related_multi_packs[i]}`],\n                item,\n                true\n            ));\n        });\n    }\n\n    return out;\n}\n\n/**\n * Asset extension for loading spritesheets.\n * @memberof PIXI\n * @type {PIXI.AssetExtension}\n */\nexport const spritesheetAsset = {\n    extension: ExtensionType.Asset,\n    /** Handle the caching of the related Spritesheet Textures */\n    cache: {\n        test: (asset: Spritesheet) => asset instanceof Spritesheet,\n        getCacheableAssets: (keys: string[], asset: Spritesheet) => getCacheableAssets(keys, asset, false),\n    },\n    /** Resolve the the resolution of the asset. */\n    resolver: {\n        test: (value: string): boolean =>\n        {\n            const tempURL = value.split('?')[0];\n            const split = tempURL.split('.');\n            const extension = split.pop();\n            const format = split.pop();\n\n            return extension === 'json' && validImages.includes(format);\n        },\n        parse: (value: string): UnresolvedAsset =>\n        {\n            const split = value.split('.');\n\n            return {\n                resolution: parseFloat(settings.RETINA_PREFIX.exec(value)?.[1] ?? '1'),\n                format: split[split.length - 2],\n                src: value,\n            };\n        },\n    },\n    /**\n     * Loader plugin that parses sprite sheets!\n     * once the JSON has been loaded this checks to see if the JSON is spritesheet data.\n     * If it is, we load the spritesheets image and parse the data into PIXI.Spritesheet\n     * All textures in the sprite sheet are then added to the cache\n     * @ignore\n     */\n    loader: {\n        name: 'spritesheetLoader',\n\n        extension: {\n            type: ExtensionType.LoadParser,\n            priority: LoaderParserPriority.Normal,\n        },\n\n        async testParse(asset: SpriteSheetJson, options: ResolvedAsset): Promise<boolean>\n        {\n            return (utils.path.extname(options.src).toLowerCase() === '.json' && !!asset.frames);\n        },\n\n        async parse(asset: SpriteSheetJson, options: ResolvedAsset, loader: Loader): Promise<Spritesheet>\n        {\n            const {\n                texture: imageTexture, // if user need to use preloaded texture\n                imageFilename, // if user need to use custom filename (not from jsonFile.meta.image)\n                cachePrefix, // if user need to use custom cache prefix\n            } = options?.data ?? {};\n\n            let basePath = utils.path.dirname(options.src);\n\n            if (basePath && basePath.lastIndexOf('/') !== (basePath.length - 1))\n            {\n                basePath += '/';\n            }\n\n            let texture: Texture;\n\n            if (imageTexture && imageTexture.baseTexture)\n            {\n                texture = imageTexture;\n            }\n            else\n            {\n                const imagePath = copySearchParams(basePath + (imageFilename ?? asset.meta.image), options.src);\n\n                const assets = await loader.load<Texture>([imagePath]);\n\n                texture = assets[imagePath];\n            }\n\n            const spritesheet = new Spritesheet({\n                texture: texture.baseTexture,\n                data: asset,\n                resolutionFilename: options.src,\n                cachePrefix,\n            });\n\n            await spritesheet.parse();\n\n            // Check and add the multi atlas\n            // Heavily influenced and based on https://github.com/rocket-ua/pixi-tps-loader/blob/master/src/ResourceLoader.js\n            // eslint-disable-next-line camelcase\n            const multiPacks = asset?.meta?.related_multi_packs;\n\n            if (Array.isArray(multiPacks))\n            {\n                const promises: Promise<Spritesheet<SpriteSheetJson>>[] = [];\n\n                for (const item of multiPacks)\n                {\n                    if (typeof item !== 'string')\n                    {\n                        continue;\n                    }\n\n                    let itemUrl = basePath + item;\n\n                    // Check if the file wasn't already added as multipack\n                    if (options.data?.ignoreMultiPack)\n                    {\n                        continue;\n                    }\n\n                    itemUrl = copySearchParams(itemUrl, options.src);\n\n                    promises.push(loader.load<Spritesheet<SpriteSheetJson>>({\n                        src: itemUrl,\n                        data: {\n                            ignoreMultiPack: true,\n                        }\n                    }));\n                }\n\n                const res = await Promise.all(promises);\n\n                spritesheet.linkedSheets = res;\n                res.forEach((item) =>\n                {\n                    item.linkedSheets = [spritesheet].concat(spritesheet.linkedSheets.filter((sp) => (sp !== item)));\n                });\n            }\n\n            return spritesheet;\n        },\n\n        unload(spritesheet: Spritesheet)\n        {\n            spritesheet.destroy(true);\n        },\n    },\n} as AssetExtension<Spritesheet | SpriteSheetJson>;\n\nextensions.add(spritesheetAsset);\n"],"names":[],"mappings":"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"}