ba-memorial-lobby-wallpaper-toolkit 0.3.0 → 0.5.0

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.
@@ -0,0 +1,6 @@
1
+ export declare const TIER_SCALES: {
2
+ readonly "4k": 2;
3
+ readonly "8k": 4;
4
+ };
5
+ export declare function assetLayout(config: Record<string, any>): Record<string, any>;
6
+ //# sourceMappingURL=asset-layout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-layout.d.ts","sourceRoot":"","sources":["../src/asset-layout.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,WAAW;aAAK,IAAI,EAAE,CAAC;aAAE,IAAI,EAAE,CAAC;CAAW,CAAC;AAEzD,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAgB5E"}
@@ -0,0 +1,23 @@
1
+ import path from "node:path";
2
+ export const TIER_SCALES = { "4k": 2, "8k": 4 };
3
+ export function assetLayout(config) {
4
+ const { PROJECT, WALLPAPER_DEFINITION: definition, VOICE_LOCALES, DIALOGUES } = config;
5
+ const binary = definition.model.binary;
6
+ const binaryBase = path.posix.basename(binary).replace(/\.(skel|json)$/, "");
7
+ const binaryDir = path.posix.dirname(binary);
8
+ const atlases = Object.entries(definition.model.atlases);
9
+ const baseTierEntry = atlases.find(([, atlasPath]) => path.posix.dirname(atlasPath) === binaryDir);
10
+ if (!baseTierEntry)
11
+ throw new Error("config.model.atlases must include one tier whose path shares the model.binary directory");
12
+ const [baseTier, baseAtlasPath] = baseTierEntry;
13
+ const tierFolders = new Map(atlases.map(([tier, atlasPath]) => [tier, path.posix.dirname(atlasPath).split("/").pop()]));
14
+ const voice = [];
15
+ for (const locale of VOICE_LOCALES)
16
+ for (const dialogue of DIALOGUES)
17
+ for (const line of dialogue.lines) {
18
+ const id = line.id.toLowerCase();
19
+ voice.push({ locale, id, relative: `audio/${locale}/${id}.ogg` });
20
+ }
21
+ return { slug: PROJECT.slug, binaryBase, baseTier, baseAtlasPath, tierFolders, voice, bgmFile: definition.audio?.bgm ? path.posix.basename(definition.audio.bgm.path) : null, bgm: definition.audio?.bgm ?? null, dialogueCount: DIALOGUES.length };
22
+ }
23
+ //# sourceMappingURL=asset-layout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-layout.js","sourceRoot":"","sources":["../src/asset-layout.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,CAAC,MAAM,WAAW,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAW,CAAC;AAEzD,MAAM,UAAU,WAAW,CAAC,MAA2B;IACrD,MAAM,EAAE,OAAO,EAAE,oBAAoB,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;IACvF,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC;IACvC,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;IAC7E,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,OAAO,CAAuB,CAAC;IAC/E,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,SAAS,CAAC,CAAC;IACnG,IAAI,CAAC,aAAa;QAAE,MAAM,IAAI,KAAK,CAAC,yFAAyF,CAAC,CAAC;IAC/H,MAAM,CAAC,QAAQ,EAAE,aAAa,CAAC,GAAG,aAAa,CAAC;IAChD,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;IACxH,MAAM,KAAK,GAAG,EAAE,CAAC;IACjB,KAAK,MAAM,MAAM,IAAI,aAAa;QAAE,KAAK,MAAM,QAAQ,IAAI,SAAS;YAAE,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;gBACxG,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC;gBACjC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,SAAS,MAAM,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YACpE,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,aAAa,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,UAAU,CAAC,KAAK,EAAE,GAAG,IAAI,IAAI,EAAE,aAAa,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC;AACtP,CAAC"}
@@ -0,0 +1,20 @@
1
+ export declare function sha256(bytes: Uint8Array): string;
2
+ export interface VerifiedCopyOptions {
3
+ source: string;
4
+ target: string;
5
+ expectedHash?: string;
6
+ checksums?: ReadonlyMap<string, string>;
7
+ checksumKey?: string;
8
+ }
9
+ export declare function parseChecksumManifest(content: string, source?: string): Map<string, string>;
10
+ export declare function copyVerifiedFile(options: VerifiedCopyOptions): Promise<Buffer>;
11
+ export interface UpscaledPngOptions {
12
+ source: string;
13
+ original: string;
14
+ target: string;
15
+ scale: number;
16
+ }
17
+ export declare function copyValidatedUpscaledPng(options: UpscaledPngOptions): Promise<void>;
18
+ export declare function writeScaledAtlasFile(source: string, target: string, scale: number): Promise<void>;
19
+ export declare function copyRuntimeFile(source: string, target: string, stripSourceMap?: boolean): Promise<void>;
20
+ //# sourceMappingURL=asset-preparation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-preparation.d.ts","sourceRoot":"","sources":["../src/asset-preparation.ts"],"names":[],"mappings":"AAIA,wBAAgB,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAEhD;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAsB,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAQxG;AAED,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CASpF;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,wBAAwB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CASzF;AAED,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIvG;AAED,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAK3G"}
@@ -0,0 +1,58 @@
1
+ import { copyFile, mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { createHash } from "node:crypto";
3
+ import path from "node:path";
4
+ export function sha256(bytes) {
5
+ return createHash("sha256").update(bytes).digest("hex");
6
+ }
7
+ export function parseChecksumManifest(content, source = "checksum manifest") {
8
+ const manifest = new Map();
9
+ for (const line of content.trim().split(/\r?\n/).filter(Boolean)) {
10
+ const match = /^([a-f0-9]{64})\s{2}(.+)$/.exec(line);
11
+ if (!match)
12
+ throw new Error(`Invalid checksum line in ${source}: ${line}`);
13
+ manifest.set(match[2].replace(/\//g, path.sep), match[1]);
14
+ }
15
+ return manifest;
16
+ }
17
+ export async function copyVerifiedFile(options) {
18
+ const bytes = await readFile(options.source);
19
+ const expectedHash = options.expectedHash ?? (options.checksumKey ? options.checksums?.get(options.checksumKey) : undefined);
20
+ if (!expectedHash)
21
+ throw new Error(`No pinned checksum for ${options.checksumKey ?? options.source}`);
22
+ const actualHash = sha256(bytes);
23
+ if (actualHash !== expectedHash)
24
+ throw new Error(`${options.checksumKey ?? options.source} failed SHA-256 verification: ${actualHash}`);
25
+ await mkdir(path.dirname(options.target), { recursive: true });
26
+ await copyFile(options.source, options.target);
27
+ return bytes;
28
+ }
29
+ export async function copyValidatedUpscaledPng(options) {
30
+ const [upscaled, original] = await Promise.all([readFile(options.source), readFile(options.original)]);
31
+ const dimensions = pngDimensions(upscaled, options.source);
32
+ const originalDimensions = pngDimensions(original, options.original);
33
+ if (dimensions.width !== originalDimensions.width * options.scale || dimensions.height !== originalDimensions.height * options.scale || dimensions.colorType !== 6) {
34
+ throw new Error(`${options.source} is not a ${options.scale}x RGBA upscale of ${options.original}: ${dimensions.width}x${dimensions.height}, color type ${dimensions.colorType}`);
35
+ }
36
+ await mkdir(path.dirname(options.target), { recursive: true });
37
+ await copyFile(options.source, options.target);
38
+ }
39
+ export async function writeScaledAtlasFile(source, target, scale) {
40
+ const atlasText = await readFile(source, "utf8");
41
+ await mkdir(path.dirname(target), { recursive: true });
42
+ await writeFile(target, scaleAtlas(atlasText, scale), "utf8");
43
+ }
44
+ export async function copyRuntimeFile(source, target, stripSourceMap = false) {
45
+ const bytes = await readFile(source);
46
+ const content = stripSourceMap ? bytes.toString("utf8").replace(/^\/\/# sourceMappingURL=.*\r?\n?/gm, "") : bytes;
47
+ await mkdir(path.dirname(target), { recursive: true });
48
+ await writeFile(target, content);
49
+ }
50
+ function pngDimensions(bytes, source) {
51
+ if (bytes.subarray(1, 4).toString("ascii") !== "PNG")
52
+ throw new Error(`Invalid PNG file: ${source}`);
53
+ return { width: bytes.readUInt32BE(16), height: bytes.readUInt32BE(20), colorType: bytes[25] };
54
+ }
55
+ function scaleAtlas(atlasText, scale) {
56
+ return atlasText.replace(/^(\s*)(size|xy|orig|offset):\s*(\d+),\s*(\d+)\s*$/gm, (_, indent, key, first, second) => `${indent}${key}: ${Number(first) * scale}, ${Number(second) * scale}`);
57
+ }
58
+ //# sourceMappingURL=asset-preparation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-preparation.js","sourceRoot":"","sources":["../src/asset-preparation.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,7 @@
1
1
  export * from "./checksums.js";
2
+ export * from "./asset-preparation.js";
3
+ export * from "./asset-layout.js";
4
+ export * from "./media.js";
2
5
  export * from "./distribution-validation.js";
3
6
  export * from "./model-assets.js";
4
7
  export * from "./model-assets.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,iBAAiB,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,7 @@
1
1
  export * from "./checksums.js";
2
+ export * from "./asset-preparation.js";
3
+ export * from "./asset-layout.js";
4
+ export * from "./media.js";
2
5
  export * from "./distribution-validation.js";
3
6
  export * from "./model-assets.js";
4
7
  export * from "./model-assets.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,iBAAiB,CAAC"}
@@ -0,0 +1,6 @@
1
+ export declare function gifMetadata(bytes: Buffer, source?: string): {
2
+ width: number;
3
+ height: number;
4
+ frames: number;
5
+ };
6
+ //# sourceMappingURL=media.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../src/media.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,SAAQ,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAc5G"}
package/dist/media.js ADDED
@@ -0,0 +1,37 @@
1
+ export function gifMetadata(bytes, source = "GIF") {
2
+ const signature = bytes.subarray(0, 6).toString("ascii");
3
+ if (signature !== "GIF87a" && signature !== "GIF89a")
4
+ throw new Error(`Invalid GIF file: ${source}`);
5
+ const width = bytes.readUInt16LE(6);
6
+ const height = bytes.readUInt16LE(8);
7
+ const packed = bytes[10];
8
+ let offset = 13 + ((packed & 0x80) ? 3 * (2 ** ((packed & 0x07) + 1)) : 0);
9
+ let frames = 0;
10
+ const skipSubBlocks = () => { while (offset < bytes.length) {
11
+ const length = bytes[offset++];
12
+ if (length === 0)
13
+ return;
14
+ offset += length;
15
+ } throw new Error(`Truncated GIF data: ${source}`); };
16
+ while (offset < bytes.length) {
17
+ const marker = bytes[offset++];
18
+ if (marker === 0x3b)
19
+ break;
20
+ if (marker === 0x21) {
21
+ offset += 1;
22
+ skipSubBlocks();
23
+ continue;
24
+ }
25
+ if (marker !== 0x2c || offset + 9 > bytes.length)
26
+ throw new Error(`Invalid GIF block: ${source}`);
27
+ frames += 1;
28
+ const imagePacked = bytes[offset + 8];
29
+ offset += 9;
30
+ if (imagePacked & 0x80)
31
+ offset += 3 * (2 ** ((imagePacked & 0x07) + 1));
32
+ offset += 1;
33
+ skipSubBlocks();
34
+ }
35
+ return { width, height, frames };
36
+ }
37
+ //# sourceMappingURL=media.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media.js","sourceRoot":"","sources":["../src/media.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,WAAW,CAAC,KAAa,EAAE,MAAM,GAAG,KAAK;IACvD,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACzD,IAAI,SAAS,KAAK,QAAQ,IAAI,SAAS,KAAK,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,MAAM,EAAE,CAAC,CAAC;IACrG,MAAM,KAAK,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAAC,MAAM,MAAM,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAAC,MAAM,MAAM,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC;IACpG,IAAI,MAAM,GAAG,EAAE,GAAG,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAAC,IAAI,MAAM,GAAG,CAAC,CAAC;IAC3F,MAAM,aAAa,GAAG,GAAG,EAAE,GAAG,OAAO,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QAAC,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QAAC,IAAI,MAAM,KAAK,CAAC;YAAE,OAAO;QAAC,MAAM,IAAI,MAAM,CAAC;IAAC,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,uBAAuB,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAChM,OAAO,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QAAC,IAAI,MAAM,KAAK,IAAI;YAAE,MAAM;QAC3D,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YAAC,MAAM,IAAI,CAAC,CAAC;YAAC,aAAa,EAAE,CAAC;YAAC,SAAS;QAAC,CAAC;QAChE,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,MAAM,EAAE,CAAC,CAAC;QAClG,MAAM,IAAI,CAAC,CAAC;QAAC,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAAC,MAAM,IAAI,CAAC,CAAC;QAChE,IAAI,WAAW,GAAG,IAAI;YAAE,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAAC,MAAM,IAAI,CAAC,CAAC;QAAC,aAAa,EAAE,CAAC;IACxG,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AACnC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ba-memorial-lobby-wallpaper-toolkit",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",