const portraitModules = import.meta.glob('../../assets/images/portraits/*.png', { eager: true, import: 'default' }) as Record; const legacyPortraitSlugs: Record = { liuBei: 'liu-bei', guanYu: 'guan-yu', zhangFei: 'zhang-fei', zhugeLiang: 'zhuge-liang', zhaoYun: 'zhao-yun', jiangWei: 'jiang-wei', simaYi: 'sima-yi' }; const speakerPortraitKeys: Record = { 유비: 'liuBei', 관우: 'guanYu', 장비: 'zhangFei', 제갈량: 'zhugeLiang', 조운: 'zhaoYun', 강유: 'jiangWei', 사마의: 'simaYi', 미축: 'mi-zhu', 간옹: 'jian-yong', 손건: 'sun-qian', 마량: 'ma-liang', 방통: 'pang-tong', 법정: 'fa-zheng', 황충: 'huang-zhong', 위연: 'wei-yan', 마초: 'ma-chao', 마대: 'ma-dai', 왕평: 'wang-ping', 이엄: 'li-yan', 오의: 'wu-yi', 이적: 'yi-ji', 공지: 'gong-zhi', 엄안: 'yan-yan', 황권: 'huang-quan', 맹획: 'meng-huo', 주유: 'zhou-yu', 조조: 'cao-cao' }; function fileSlugFromPath(path: string) { const fileName = path.split('/').pop() ?? path; return fileName.replace(/\.png$/i, ''); } function camelToKebab(value: string) { return value.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`); } export const portraitAssets: Record = Object.fromEntries( Object.entries(portraitModules).map(([path, url]) => [fileSlugFromPath(path), url]) ); export type PortraitAssetEntry = { textureKey: string; url: string; }; export function portraitSlugForKey(key: string) { return legacyPortraitSlugs[key] ?? camelToKebab(key); } export function portraitTextureKey(key: string) { const slug = portraitSlugForKey(key); return portraitAssets[slug] ? `portrait-${slug}` : undefined; } export function portraitAssetEntriesForKey(key: string): PortraitAssetEntry[] { const slug = portraitSlugForKey(key); const prefix = `${slug}-`; return Object.keys(portraitAssets) .filter((candidate) => candidate === slug || candidate.startsWith(prefix)) .sort() .map((candidate) => ({ textureKey: `portrait-${candidate}`, url: portraitAssets[candidate] })); } export function portraitTextureKeysForKey(key: string) { const slug = portraitSlugForKey(key); const prefix = `${slug}-`; const slugs = Object.keys(portraitAssets) .filter((candidate) => candidate === slug || candidate.startsWith(prefix)) .sort(); return Array.from(new Set(slugs.map((candidate) => `portrait-${candidate}`))); } export function portraitKeyForSpeaker(speaker?: string) { return speaker ? speakerPortraitKeys[speaker] : undefined; }