swf-toolkit 0.0.0-stage → 0.1.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.
- package/LICENSE +21 -0
- package/README.md +125 -2
- package/README.tr.md +126 -0
- package/dist/abc/abc-file.d.ts +168 -0
- package/dist/abc/abc-file.js +656 -0
- package/dist/abc/analysis.d.ts +36 -0
- package/dist/abc/analysis.js +213 -0
- package/dist/abc/code.d.ts +59 -0
- package/dist/abc/code.js +379 -0
- package/dist/abc/constants.d.ts +80 -0
- package/dist/abc/constants.js +93 -0
- package/dist/abc/interner.d.ts +46 -0
- package/dist/abc/interner.js +168 -0
- package/dist/abc/model.d.ts +40 -0
- package/dist/abc/model.js +146 -0
- package/dist/abc/opcodes.d.ts +39 -0
- package/dist/abc/opcodes.js +196 -0
- package/dist/abc/pcode/assembler.d.ts +42 -0
- package/dist/abc/pcode/assembler.js +635 -0
- package/dist/abc/pcode/disassembler.d.ts +17 -0
- package/dist/abc/pcode/disassembler.js +147 -0
- package/dist/abc/pcode/format.d.ts +23 -0
- package/dist/abc/pcode/format.js +131 -0
- package/dist/abc/pcode/lexer.d.ts +34 -0
- package/dist/abc/pcode/lexer.js +183 -0
- package/dist/assets/assets.d.ts +26 -0
- package/dist/assets/assets.js +151 -0
- package/dist/assets/images.d.ts +31 -0
- package/dist/assets/images.js +238 -0
- package/dist/assets/png.d.ts +12 -0
- package/dist/assets/png.js +196 -0
- package/dist/assets/sounds.d.ts +37 -0
- package/dist/assets/sounds.js +236 -0
- package/dist/avm1/avm1.d.ts +55 -0
- package/dist/avm1/avm1.js +642 -0
- package/dist/avm1/project.d.ts +16 -0
- package/dist/avm1/project.js +81 -0
- package/dist/cjs/abc/abc-file.d.ts +168 -0
- package/dist/cjs/abc/abc-file.js +663 -0
- package/dist/cjs/abc/analysis.d.ts +36 -0
- package/dist/cjs/abc/analysis.js +221 -0
- package/dist/cjs/abc/code.d.ts +59 -0
- package/dist/cjs/abc/code.js +387 -0
- package/dist/cjs/abc/constants.d.ts +80 -0
- package/dist/cjs/abc/constants.js +97 -0
- package/dist/cjs/abc/interner.d.ts +46 -0
- package/dist/cjs/abc/interner.js +172 -0
- package/dist/cjs/abc/model.d.ts +40 -0
- package/dist/cjs/abc/model.js +155 -0
- package/dist/cjs/abc/opcodes.d.ts +39 -0
- package/dist/cjs/abc/opcodes.js +201 -0
- package/dist/cjs/abc/pcode/assembler.d.ts +42 -0
- package/dist/cjs/abc/pcode/assembler.js +640 -0
- package/dist/cjs/abc/pcode/disassembler.d.ts +17 -0
- package/dist/cjs/abc/pcode/disassembler.js +152 -0
- package/dist/cjs/abc/pcode/format.d.ts +23 -0
- package/dist/cjs/abc/pcode/format.js +141 -0
- package/dist/cjs/abc/pcode/lexer.d.ts +34 -0
- package/dist/cjs/abc/pcode/lexer.js +188 -0
- package/dist/cjs/assets/assets.d.ts +26 -0
- package/dist/cjs/assets/assets.js +159 -0
- package/dist/cjs/assets/images.d.ts +31 -0
- package/dist/cjs/assets/images.js +246 -0
- package/dist/cjs/assets/png.d.ts +12 -0
- package/dist/cjs/assets/png.js +202 -0
- package/dist/cjs/assets/sounds.d.ts +37 -0
- package/dist/cjs/assets/sounds.js +246 -0
- package/dist/cjs/avm1/avm1.d.ts +55 -0
- package/dist/cjs/avm1/avm1.js +649 -0
- package/dist/cjs/avm1/project.d.ts +16 -0
- package/dist/cjs/avm1/project.js +88 -0
- package/dist/cjs/compiler/ast.d.ts +285 -0
- package/dist/cjs/compiler/ast.js +3 -0
- package/dist/cjs/compiler/class-compiler.d.ts +34 -0
- package/dist/cjs/compiler/class-compiler.js +440 -0
- package/dist/cjs/compiler/codegen.d.ts +144 -0
- package/dist/cjs/compiler/codegen.js +1589 -0
- package/dist/cjs/compiler/lexer.d.ts +27 -0
- package/dist/cjs/compiler/lexer.js +254 -0
- package/dist/cjs/compiler/parser.d.ts +58 -0
- package/dist/cjs/compiler/parser.js +989 -0
- package/dist/cjs/compiler/program.d.ts +29 -0
- package/dist/cjs/compiler/program.js +36 -0
- package/dist/cjs/compiler/scope.d.ts +22 -0
- package/dist/cjs/compiler/scope.js +242 -0
- package/dist/cjs/compression/lzma.d.ts +37 -0
- package/dist/cjs/compression/lzma.js +575 -0
- package/dist/cjs/compression/swf-container.d.ts +19 -0
- package/dist/cjs/compression/swf-container.js +92 -0
- package/dist/cjs/decompiler/ast.d.ts +228 -0
- package/dist/cjs/decompiler/ast.js +455 -0
- package/dist/cjs/decompiler/cfg.d.ts +40 -0
- package/dist/cjs/decompiler/cfg.js +236 -0
- package/dist/cjs/decompiler/class-printer.d.ts +9 -0
- package/dist/cjs/decompiler/class-printer.js +173 -0
- package/dist/cjs/decompiler/method.d.ts +41 -0
- package/dist/cjs/decompiler/method.js +436 -0
- package/dist/cjs/decompiler/simulate.d.ts +55 -0
- package/dist/cjs/decompiler/simulate.js +591 -0
- package/dist/cjs/decompiler/structure.d.ts +48 -0
- package/dist/cjs/decompiler/structure.js +764 -0
- package/dist/cjs/errors.d.ts +11 -0
- package/dist/cjs/errors.js +25 -0
- package/dist/cjs/index.d.ts +41 -0
- package/dist/cjs/index.js +82 -0
- package/dist/cjs/io/reader.d.ts +48 -0
- package/dist/cjs/io/reader.js +180 -0
- package/dist/cjs/io/writer.d.ts +37 -0
- package/dist/cjs/io/writer.js +175 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/project/pcode-project.d.ts +32 -0
- package/dist/cjs/project/pcode-project.js +210 -0
- package/dist/cjs/project/source-export.d.ts +12 -0
- package/dist/cjs/project/source-export.js +51 -0
- package/dist/cjs/project/source-import.d.ts +13 -0
- package/dist/cjs/project/source-import.js +73 -0
- package/dist/cjs/swf/swf.d.ts +63 -0
- package/dist/cjs/swf/swf.js +147 -0
- package/dist/cjs/swf/tag-codes.d.ts +77 -0
- package/dist/cjs/swf/tag-codes.js +109 -0
- package/dist/cjs/swf/tags.d.ts +118 -0
- package/dist/cjs/swf/tags.js +330 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +296 -0
- package/dist/compiler/ast.d.ts +285 -0
- package/dist/compiler/ast.js +2 -0
- package/dist/compiler/class-compiler.d.ts +34 -0
- package/dist/compiler/class-compiler.js +437 -0
- package/dist/compiler/codegen.d.ts +144 -0
- package/dist/compiler/codegen.js +1585 -0
- package/dist/compiler/lexer.d.ts +27 -0
- package/dist/compiler/lexer.js +249 -0
- package/dist/compiler/parser.d.ts +58 -0
- package/dist/compiler/parser.js +984 -0
- package/dist/compiler/program.d.ts +29 -0
- package/dist/compiler/program.js +32 -0
- package/dist/compiler/scope.d.ts +22 -0
- package/dist/compiler/scope.js +238 -0
- package/dist/compression/lzma.d.ts +37 -0
- package/dist/compression/lzma.js +569 -0
- package/dist/compression/swf-container.d.ts +19 -0
- package/dist/compression/swf-container.js +87 -0
- package/dist/decompiler/ast.d.ts +228 -0
- package/dist/decompiler/ast.js +441 -0
- package/dist/decompiler/cfg.d.ts +40 -0
- package/dist/decompiler/cfg.js +231 -0
- package/dist/decompiler/class-printer.d.ts +9 -0
- package/dist/decompiler/class-printer.js +170 -0
- package/dist/decompiler/method.d.ts +41 -0
- package/dist/decompiler/method.js +427 -0
- package/dist/decompiler/simulate.d.ts +55 -0
- package/dist/decompiler/simulate.js +586 -0
- package/dist/decompiler/structure.d.ts +48 -0
- package/dist/decompiler/structure.js +760 -0
- package/dist/errors.d.ts +11 -0
- package/dist/errors.js +20 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.js +49 -0
- package/dist/io/reader.d.ts +48 -0
- package/dist/io/reader.js +176 -0
- package/dist/io/writer.d.ts +37 -0
- package/dist/io/writer.js +169 -0
- package/dist/project/pcode-project.d.ts +32 -0
- package/dist/project/pcode-project.js +203 -0
- package/dist/project/source-export.d.ts +12 -0
- package/dist/project/source-export.js +47 -0
- package/dist/project/source-import.d.ts +13 -0
- package/dist/project/source-import.js +70 -0
- package/dist/swf/swf.d.ts +63 -0
- package/dist/swf/swf.js +143 -0
- package/dist/swf/tag-codes.d.ts +77 -0
- package/dist/swf/tag-codes.js +105 -0
- package/dist/swf/tags.d.ts +118 -0
- package/dist/swf/tags.js +316 -0
- package/package.json +71 -4
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CHARACTER_DEFINING_TAGS = exports.TagCode = void 0;
|
|
4
|
+
exports.tagName = tagName;
|
|
5
|
+
/** SWF tag codes (SWF File Format Specification v19). */
|
|
6
|
+
exports.TagCode = {
|
|
7
|
+
End: 0,
|
|
8
|
+
ShowFrame: 1,
|
|
9
|
+
DefineShape: 2,
|
|
10
|
+
FreeCharacter: 3,
|
|
11
|
+
PlaceObject: 4,
|
|
12
|
+
RemoveObject: 5,
|
|
13
|
+
DefineBits: 6,
|
|
14
|
+
DefineButton: 7,
|
|
15
|
+
JPEGTables: 8,
|
|
16
|
+
SetBackgroundColor: 9,
|
|
17
|
+
DefineFont: 10,
|
|
18
|
+
DefineText: 11,
|
|
19
|
+
DoAction: 12,
|
|
20
|
+
DefineFontInfo: 13,
|
|
21
|
+
DefineSound: 14,
|
|
22
|
+
StartSound: 15,
|
|
23
|
+
DefineButtonSound: 17,
|
|
24
|
+
SoundStreamHead: 18,
|
|
25
|
+
SoundStreamBlock: 19,
|
|
26
|
+
DefineBitsLossless: 20,
|
|
27
|
+
DefineBitsJPEG2: 21,
|
|
28
|
+
DefineShape2: 22,
|
|
29
|
+
DefineButtonCxform: 23,
|
|
30
|
+
Protect: 24,
|
|
31
|
+
PlaceObject2: 26,
|
|
32
|
+
RemoveObject2: 28,
|
|
33
|
+
DefineShape3: 32,
|
|
34
|
+
DefineText2: 33,
|
|
35
|
+
DefineButton2: 34,
|
|
36
|
+
DefineBitsJPEG3: 35,
|
|
37
|
+
DefineBitsLossless2: 36,
|
|
38
|
+
DefineEditText: 37,
|
|
39
|
+
DefineSprite: 39,
|
|
40
|
+
ProductInfo: 41,
|
|
41
|
+
FrameLabel: 43,
|
|
42
|
+
SoundStreamHead2: 45,
|
|
43
|
+
DefineMorphShape: 46,
|
|
44
|
+
DefineFont2: 48,
|
|
45
|
+
ExportAssets: 56,
|
|
46
|
+
ImportAssets: 57,
|
|
47
|
+
EnableDebugger: 58,
|
|
48
|
+
DoInitAction: 59,
|
|
49
|
+
DefineVideoStream: 60,
|
|
50
|
+
VideoFrame: 61,
|
|
51
|
+
DefineFontInfo2: 62,
|
|
52
|
+
DebugID: 63,
|
|
53
|
+
EnableDebugger2: 64,
|
|
54
|
+
ScriptLimits: 65,
|
|
55
|
+
SetTabIndex: 66,
|
|
56
|
+
FileAttributes: 69,
|
|
57
|
+
PlaceObject3: 70,
|
|
58
|
+
ImportAssets2: 71,
|
|
59
|
+
DoABC: 72,
|
|
60
|
+
DefineFontAlignZones: 73,
|
|
61
|
+
CSMTextSettings: 74,
|
|
62
|
+
DefineFont3: 75,
|
|
63
|
+
SymbolClass: 76,
|
|
64
|
+
Metadata: 77,
|
|
65
|
+
DefineScalingGrid: 78,
|
|
66
|
+
DoABC2: 82,
|
|
67
|
+
DefineShape4: 83,
|
|
68
|
+
DefineMorphShape2: 84,
|
|
69
|
+
DefineSceneAndFrameLabelData: 86,
|
|
70
|
+
DefineBinaryData: 87,
|
|
71
|
+
DefineFontName: 88,
|
|
72
|
+
StartSound2: 89,
|
|
73
|
+
DefineBitsJPEG4: 90,
|
|
74
|
+
DefineFont4: 91,
|
|
75
|
+
EnableTelemetry: 93,
|
|
76
|
+
PlaceObject4: 94,
|
|
77
|
+
};
|
|
78
|
+
const NAMES = new Map(Object.entries(exports.TagCode).map(([k, v]) => [v, k]));
|
|
79
|
+
function tagName(code) {
|
|
80
|
+
return NAMES.get(code) ?? `Unknown(${code})`;
|
|
81
|
+
}
|
|
82
|
+
/** Tags whose body starts with the u16 id of the character they define. */
|
|
83
|
+
exports.CHARACTER_DEFINING_TAGS = new Set([
|
|
84
|
+
exports.TagCode.DefineShape,
|
|
85
|
+
exports.TagCode.DefineBits,
|
|
86
|
+
exports.TagCode.DefineButton,
|
|
87
|
+
exports.TagCode.DefineFont,
|
|
88
|
+
exports.TagCode.DefineText,
|
|
89
|
+
exports.TagCode.DefineSound,
|
|
90
|
+
exports.TagCode.DefineBitsLossless,
|
|
91
|
+
exports.TagCode.DefineBitsJPEG2,
|
|
92
|
+
exports.TagCode.DefineShape2,
|
|
93
|
+
exports.TagCode.DefineShape3,
|
|
94
|
+
exports.TagCode.DefineText2,
|
|
95
|
+
exports.TagCode.DefineButton2,
|
|
96
|
+
exports.TagCode.DefineBitsJPEG3,
|
|
97
|
+
exports.TagCode.DefineBitsLossless2,
|
|
98
|
+
exports.TagCode.DefineEditText,
|
|
99
|
+
exports.TagCode.DefineSprite,
|
|
100
|
+
exports.TagCode.DefineMorphShape,
|
|
101
|
+
exports.TagCode.DefineFont2,
|
|
102
|
+
exports.TagCode.DefineVideoStream,
|
|
103
|
+
exports.TagCode.DefineFont3,
|
|
104
|
+
exports.TagCode.DefineShape4,
|
|
105
|
+
exports.TagCode.DefineMorphShape2,
|
|
106
|
+
exports.TagCode.DefineBinaryData,
|
|
107
|
+
exports.TagCode.DefineBitsJPEG4,
|
|
108
|
+
exports.TagCode.DefineFont4,
|
|
109
|
+
]);
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { ByteWriter } from '../io/writer.js';
|
|
2
|
+
import { AbcFile } from '../abc/abc-file.js';
|
|
3
|
+
/** Base class for all SWF tags. */
|
|
4
|
+
export declare abstract class Tag {
|
|
5
|
+
abstract readonly code: number;
|
|
6
|
+
/**
|
|
7
|
+
* Write this tag with a long (6-byte) record header even if its body is
|
|
8
|
+
* shorter than 63 bytes. Set automatically when parsed from a file that
|
|
9
|
+
* used the long form, so unmodified files round-trip byte-for-byte.
|
|
10
|
+
*/
|
|
11
|
+
longHeader: boolean;
|
|
12
|
+
get name(): string;
|
|
13
|
+
/** Serialised tag body (without the record header). */
|
|
14
|
+
abstract encodeBody(): Uint8Array;
|
|
15
|
+
/** Character id for character-defining tags, otherwise `undefined`. */
|
|
16
|
+
get characterId(): number | undefined;
|
|
17
|
+
}
|
|
18
|
+
/** A tag kept as opaque bytes. Every tag type not modelled explicitly is a RawTag. */
|
|
19
|
+
export declare class RawTag extends Tag {
|
|
20
|
+
code: number;
|
|
21
|
+
data: Uint8Array;
|
|
22
|
+
constructor(code: number, data: Uint8Array);
|
|
23
|
+
get characterId(): number | undefined;
|
|
24
|
+
/** Change the character id of a character-defining tag in place. */
|
|
25
|
+
setCharacterId(id: number): void;
|
|
26
|
+
encodeBody(): Uint8Array;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* DoABC (72) / DoABC2 (82): an ActionScript 3 bytecode block.
|
|
30
|
+
*
|
|
31
|
+
* The ABC payload is parsed lazily on first access to {@link abc}. As long as
|
|
32
|
+
* it has not been accessed, the original bytes are written back untouched.
|
|
33
|
+
*/
|
|
34
|
+
export declare class DoABCTag extends Tag {
|
|
35
|
+
readonly code: number;
|
|
36
|
+
/** DoABC2 flags. 1 = kDoAbcLazyInitializeFlag. */
|
|
37
|
+
flags: number;
|
|
38
|
+
/** DoABC2 name. */
|
|
39
|
+
abcName: string;
|
|
40
|
+
private raw;
|
|
41
|
+
private parsed;
|
|
42
|
+
constructor(code: number, flags: number, abcName: string, abc: Uint8Array | AbcFile);
|
|
43
|
+
static create(abc: AbcFile, name?: string, flags?: number): DoABCTag;
|
|
44
|
+
/** Parsed ABC file. Parsing happens once, on first access. */
|
|
45
|
+
get abc(): AbcFile;
|
|
46
|
+
set abc(value: AbcFile);
|
|
47
|
+
/** True once the ABC has been parsed (and will therefore be re-serialised on save). */
|
|
48
|
+
get isParsed(): boolean;
|
|
49
|
+
/** Raw ABC bytes (serialises the parsed ABC if needed). */
|
|
50
|
+
abcBytes(): Uint8Array;
|
|
51
|
+
encodeBody(): Uint8Array;
|
|
52
|
+
}
|
|
53
|
+
export interface SymbolEntry {
|
|
54
|
+
id: number;
|
|
55
|
+
name: string;
|
|
56
|
+
}
|
|
57
|
+
/** SymbolClass (76) and ExportAssets (56): character id ↔ name mappings. */
|
|
58
|
+
export declare class SymbolTableTag extends Tag {
|
|
59
|
+
readonly code: number;
|
|
60
|
+
symbols: SymbolEntry[];
|
|
61
|
+
constructor(code: number, symbols: SymbolEntry[]);
|
|
62
|
+
encodeBody(): Uint8Array;
|
|
63
|
+
}
|
|
64
|
+
/** DefineSprite (39): a movie clip with its own control-tag timeline. */
|
|
65
|
+
export declare class DefineSpriteTag extends Tag {
|
|
66
|
+
spriteId: number;
|
|
67
|
+
frameCount: number;
|
|
68
|
+
tags: Tag[];
|
|
69
|
+
/** Bytes after the nested End tag (normally empty). */
|
|
70
|
+
trailing: Uint8Array;
|
|
71
|
+
readonly code: 39;
|
|
72
|
+
constructor(spriteId: number, frameCount: number, tags: Tag[],
|
|
73
|
+
/** Bytes after the nested End tag (normally empty). */
|
|
74
|
+
trailing?: Uint8Array);
|
|
75
|
+
get characterId(): number;
|
|
76
|
+
encodeBody(): Uint8Array;
|
|
77
|
+
}
|
|
78
|
+
/** DefineBinaryData (87). */
|
|
79
|
+
export declare class DefineBinaryDataTag extends Tag {
|
|
80
|
+
id: number;
|
|
81
|
+
data: Uint8Array;
|
|
82
|
+
reserved: number;
|
|
83
|
+
readonly code: 87;
|
|
84
|
+
constructor(id: number, data: Uint8Array, reserved?: number);
|
|
85
|
+
get characterId(): number;
|
|
86
|
+
encodeBody(): Uint8Array;
|
|
87
|
+
}
|
|
88
|
+
/** Metadata (77): XMP/RDF XML string. */
|
|
89
|
+
export declare class MetadataTag extends Tag {
|
|
90
|
+
xml: string;
|
|
91
|
+
readonly code: 77;
|
|
92
|
+
constructor(xml: string);
|
|
93
|
+
encodeBody(): Uint8Array;
|
|
94
|
+
}
|
|
95
|
+
/** FileAttributes (69). */
|
|
96
|
+
export declare class FileAttributesTag extends Tag {
|
|
97
|
+
flags: number;
|
|
98
|
+
readonly code: 69;
|
|
99
|
+
constructor(flags: number);
|
|
100
|
+
get useDirectBlit(): boolean;
|
|
101
|
+
get useGPU(): boolean;
|
|
102
|
+
get hasMetadata(): boolean;
|
|
103
|
+
get actionScript3(): boolean;
|
|
104
|
+
set actionScript3(v: boolean);
|
|
105
|
+
get useNetwork(): boolean;
|
|
106
|
+
set useNetwork(v: boolean);
|
|
107
|
+
encodeBody(): Uint8Array;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Reads a tag stream until (and including) the End tag or the end of data.
|
|
111
|
+
* Returns the tags and the offset right after the last consumed byte.
|
|
112
|
+
*/
|
|
113
|
+
export declare function readTags(bytes: Uint8Array, start: number, end: number): {
|
|
114
|
+
tags: Tag[];
|
|
115
|
+
end: number;
|
|
116
|
+
};
|
|
117
|
+
export declare function writeTag(w: ByteWriter, tag: Tag): void;
|
|
118
|
+
export declare function writeTags(w: ByteWriter, tags: readonly Tag[]): void;
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FileAttributesTag = exports.MetadataTag = exports.DefineBinaryDataTag = exports.DefineSpriteTag = exports.SymbolTableTag = exports.DoABCTag = exports.RawTag = exports.Tag = void 0;
|
|
4
|
+
exports.readTags = readTags;
|
|
5
|
+
exports.writeTag = writeTag;
|
|
6
|
+
exports.writeTags = writeTags;
|
|
7
|
+
const reader_js_1 = require("../io/reader.js");
|
|
8
|
+
const writer_js_1 = require("../io/writer.js");
|
|
9
|
+
const abc_file_js_1 = require("../abc/abc-file.js");
|
|
10
|
+
const tag_codes_js_1 = require("./tag-codes.js");
|
|
11
|
+
/** Base class for all SWF tags. */
|
|
12
|
+
class Tag {
|
|
13
|
+
/**
|
|
14
|
+
* Write this tag with a long (6-byte) record header even if its body is
|
|
15
|
+
* shorter than 63 bytes. Set automatically when parsed from a file that
|
|
16
|
+
* used the long form, so unmodified files round-trip byte-for-byte.
|
|
17
|
+
*/
|
|
18
|
+
longHeader = false;
|
|
19
|
+
get name() {
|
|
20
|
+
return (0, tag_codes_js_1.tagName)(this.code);
|
|
21
|
+
}
|
|
22
|
+
/** Character id for character-defining tags, otherwise `undefined`. */
|
|
23
|
+
get characterId() {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.Tag = Tag;
|
|
28
|
+
/** A tag kept as opaque bytes. Every tag type not modelled explicitly is a RawTag. */
|
|
29
|
+
class RawTag extends Tag {
|
|
30
|
+
code;
|
|
31
|
+
data;
|
|
32
|
+
constructor(code, data) {
|
|
33
|
+
super();
|
|
34
|
+
this.code = code;
|
|
35
|
+
this.data = data;
|
|
36
|
+
}
|
|
37
|
+
get characterId() {
|
|
38
|
+
if (tag_codes_js_1.CHARACTER_DEFINING_TAGS.has(this.code) && this.data.length >= 2) {
|
|
39
|
+
return this.data[0] | (this.data[1] << 8);
|
|
40
|
+
}
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
/** Change the character id of a character-defining tag in place. */
|
|
44
|
+
setCharacterId(id) {
|
|
45
|
+
if (!tag_codes_js_1.CHARACTER_DEFINING_TAGS.has(this.code))
|
|
46
|
+
throw new Error(`${this.name} does not define a character`);
|
|
47
|
+
this.data = this.data.slice();
|
|
48
|
+
this.data[0] = id & 0xff;
|
|
49
|
+
this.data[1] = (id >> 8) & 0xff;
|
|
50
|
+
}
|
|
51
|
+
encodeBody() {
|
|
52
|
+
return this.data;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
exports.RawTag = RawTag;
|
|
56
|
+
/**
|
|
57
|
+
* DoABC (72) / DoABC2 (82): an ActionScript 3 bytecode block.
|
|
58
|
+
*
|
|
59
|
+
* The ABC payload is parsed lazily on first access to {@link abc}. As long as
|
|
60
|
+
* it has not been accessed, the original bytes are written back untouched.
|
|
61
|
+
*/
|
|
62
|
+
class DoABCTag extends Tag {
|
|
63
|
+
code;
|
|
64
|
+
/** DoABC2 flags. 1 = kDoAbcLazyInitializeFlag. */
|
|
65
|
+
flags;
|
|
66
|
+
/** DoABC2 name. */
|
|
67
|
+
abcName;
|
|
68
|
+
raw;
|
|
69
|
+
parsed;
|
|
70
|
+
constructor(code, flags, abcName, abc) {
|
|
71
|
+
super();
|
|
72
|
+
this.code = code;
|
|
73
|
+
this.flags = flags;
|
|
74
|
+
this.abcName = abcName;
|
|
75
|
+
if (abc instanceof abc_file_js_1.AbcFile)
|
|
76
|
+
this.parsed = abc;
|
|
77
|
+
else
|
|
78
|
+
this.raw = abc;
|
|
79
|
+
}
|
|
80
|
+
static create(abc, name = '', flags = 1) {
|
|
81
|
+
return new DoABCTag(tag_codes_js_1.TagCode.DoABC2, flags, name, abc);
|
|
82
|
+
}
|
|
83
|
+
/** Parsed ABC file. Parsing happens once, on first access. */
|
|
84
|
+
get abc() {
|
|
85
|
+
if (!this.parsed) {
|
|
86
|
+
this.parsed = abc_file_js_1.AbcFile.parse(this.raw);
|
|
87
|
+
this.raw = undefined;
|
|
88
|
+
}
|
|
89
|
+
return this.parsed;
|
|
90
|
+
}
|
|
91
|
+
set abc(value) {
|
|
92
|
+
this.parsed = value;
|
|
93
|
+
this.raw = undefined;
|
|
94
|
+
}
|
|
95
|
+
/** True once the ABC has been parsed (and will therefore be re-serialised on save). */
|
|
96
|
+
get isParsed() {
|
|
97
|
+
return this.parsed !== undefined;
|
|
98
|
+
}
|
|
99
|
+
/** Raw ABC bytes (serialises the parsed ABC if needed). */
|
|
100
|
+
abcBytes() {
|
|
101
|
+
return this.parsed ? this.parsed.toBytes() : this.raw;
|
|
102
|
+
}
|
|
103
|
+
encodeBody() {
|
|
104
|
+
const abc = this.abcBytes();
|
|
105
|
+
if (this.code === tag_codes_js_1.TagCode.DoABC)
|
|
106
|
+
return abc;
|
|
107
|
+
const w = new writer_js_1.ByteWriter(abc.length + this.abcName.length + 8);
|
|
108
|
+
w.u32(this.flags);
|
|
109
|
+
w.cstring(this.abcName);
|
|
110
|
+
w.bytes(abc);
|
|
111
|
+
return w.toBytes();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
exports.DoABCTag = DoABCTag;
|
|
115
|
+
/** SymbolClass (76) and ExportAssets (56): character id ↔ name mappings. */
|
|
116
|
+
class SymbolTableTag extends Tag {
|
|
117
|
+
code;
|
|
118
|
+
symbols;
|
|
119
|
+
constructor(code, symbols) {
|
|
120
|
+
super();
|
|
121
|
+
this.code = code;
|
|
122
|
+
this.symbols = symbols;
|
|
123
|
+
}
|
|
124
|
+
encodeBody() {
|
|
125
|
+
const w = new writer_js_1.ByteWriter();
|
|
126
|
+
w.u16(this.symbols.length);
|
|
127
|
+
for (const s of this.symbols) {
|
|
128
|
+
w.u16(s.id);
|
|
129
|
+
w.cstring(s.name);
|
|
130
|
+
}
|
|
131
|
+
return w.toBytes();
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
exports.SymbolTableTag = SymbolTableTag;
|
|
135
|
+
/** DefineSprite (39): a movie clip with its own control-tag timeline. */
|
|
136
|
+
class DefineSpriteTag extends Tag {
|
|
137
|
+
spriteId;
|
|
138
|
+
frameCount;
|
|
139
|
+
tags;
|
|
140
|
+
trailing;
|
|
141
|
+
code = tag_codes_js_1.TagCode.DefineSprite;
|
|
142
|
+
constructor(spriteId, frameCount, tags,
|
|
143
|
+
/** Bytes after the nested End tag (normally empty). */
|
|
144
|
+
trailing = new Uint8Array(0)) {
|
|
145
|
+
super();
|
|
146
|
+
this.spriteId = spriteId;
|
|
147
|
+
this.frameCount = frameCount;
|
|
148
|
+
this.tags = tags;
|
|
149
|
+
this.trailing = trailing;
|
|
150
|
+
}
|
|
151
|
+
get characterId() {
|
|
152
|
+
return this.spriteId;
|
|
153
|
+
}
|
|
154
|
+
encodeBody() {
|
|
155
|
+
const w = new writer_js_1.ByteWriter();
|
|
156
|
+
w.u16(this.spriteId);
|
|
157
|
+
w.u16(this.frameCount);
|
|
158
|
+
writeTags(w, this.tags);
|
|
159
|
+
w.bytes(this.trailing);
|
|
160
|
+
return w.toBytes();
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
exports.DefineSpriteTag = DefineSpriteTag;
|
|
164
|
+
/** DefineBinaryData (87). */
|
|
165
|
+
class DefineBinaryDataTag extends Tag {
|
|
166
|
+
id;
|
|
167
|
+
data;
|
|
168
|
+
reserved;
|
|
169
|
+
code = tag_codes_js_1.TagCode.DefineBinaryData;
|
|
170
|
+
constructor(id, data, reserved = 0) {
|
|
171
|
+
super();
|
|
172
|
+
this.id = id;
|
|
173
|
+
this.data = data;
|
|
174
|
+
this.reserved = reserved;
|
|
175
|
+
}
|
|
176
|
+
get characterId() {
|
|
177
|
+
return this.id;
|
|
178
|
+
}
|
|
179
|
+
encodeBody() {
|
|
180
|
+
const w = new writer_js_1.ByteWriter(this.data.length + 6);
|
|
181
|
+
w.u16(this.id);
|
|
182
|
+
w.u32(this.reserved);
|
|
183
|
+
w.bytes(this.data);
|
|
184
|
+
return w.toBytes();
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
exports.DefineBinaryDataTag = DefineBinaryDataTag;
|
|
188
|
+
/** Metadata (77): XMP/RDF XML string. */
|
|
189
|
+
class MetadataTag extends Tag {
|
|
190
|
+
xml;
|
|
191
|
+
code = tag_codes_js_1.TagCode.Metadata;
|
|
192
|
+
constructor(xml) {
|
|
193
|
+
super();
|
|
194
|
+
this.xml = xml;
|
|
195
|
+
}
|
|
196
|
+
encodeBody() {
|
|
197
|
+
return new writer_js_1.ByteWriter().cstring(this.xml).toBytes();
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
exports.MetadataTag = MetadataTag;
|
|
201
|
+
/** FileAttributes (69). */
|
|
202
|
+
class FileAttributesTag extends Tag {
|
|
203
|
+
flags;
|
|
204
|
+
code = tag_codes_js_1.TagCode.FileAttributes;
|
|
205
|
+
constructor(flags) {
|
|
206
|
+
super();
|
|
207
|
+
this.flags = flags;
|
|
208
|
+
}
|
|
209
|
+
get useDirectBlit() {
|
|
210
|
+
return (this.flags & 0x40) !== 0;
|
|
211
|
+
}
|
|
212
|
+
get useGPU() {
|
|
213
|
+
return (this.flags & 0x20) !== 0;
|
|
214
|
+
}
|
|
215
|
+
get hasMetadata() {
|
|
216
|
+
return (this.flags & 0x10) !== 0;
|
|
217
|
+
}
|
|
218
|
+
get actionScript3() {
|
|
219
|
+
return (this.flags & 0x08) !== 0;
|
|
220
|
+
}
|
|
221
|
+
set actionScript3(v) {
|
|
222
|
+
this.flags = v ? this.flags | 0x08 : this.flags & ~0x08;
|
|
223
|
+
}
|
|
224
|
+
get useNetwork() {
|
|
225
|
+
return (this.flags & 0x01) !== 0;
|
|
226
|
+
}
|
|
227
|
+
set useNetwork(v) {
|
|
228
|
+
this.flags = v ? this.flags | 0x01 : this.flags & ~0x01;
|
|
229
|
+
}
|
|
230
|
+
encodeBody() {
|
|
231
|
+
return new writer_js_1.ByteWriter(4).u32(this.flags).toBytes();
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
exports.FileAttributesTag = FileAttributesTag;
|
|
235
|
+
// ---------------------------------------------------------------------------
|
|
236
|
+
// Tag stream parsing / writing
|
|
237
|
+
// ---------------------------------------------------------------------------
|
|
238
|
+
function decodeTag(code, body) {
|
|
239
|
+
const r = new reader_js_1.ByteReader(body);
|
|
240
|
+
switch (code) {
|
|
241
|
+
case tag_codes_js_1.TagCode.DoABC:
|
|
242
|
+
return new DoABCTag(code, 0, '', body);
|
|
243
|
+
case tag_codes_js_1.TagCode.DoABC2: {
|
|
244
|
+
const flags = r.u32();
|
|
245
|
+
const name = r.cstring();
|
|
246
|
+
return new DoABCTag(code, flags, name, r.rest());
|
|
247
|
+
}
|
|
248
|
+
case tag_codes_js_1.TagCode.SymbolClass:
|
|
249
|
+
case tag_codes_js_1.TagCode.ExportAssets: {
|
|
250
|
+
const count = r.u16();
|
|
251
|
+
const symbols = [];
|
|
252
|
+
for (let i = 0; i < count; i++)
|
|
253
|
+
symbols.push({ id: r.u16(), name: r.cstring() });
|
|
254
|
+
if (!r.eof)
|
|
255
|
+
return new RawTag(code, body);
|
|
256
|
+
return new SymbolTableTag(code, symbols);
|
|
257
|
+
}
|
|
258
|
+
case tag_codes_js_1.TagCode.DefineSprite: {
|
|
259
|
+
const id = r.u16();
|
|
260
|
+
const frameCount = r.u16();
|
|
261
|
+
const { tags, end } = readTags(body, r.pos, body.length);
|
|
262
|
+
return new DefineSpriteTag(id, frameCount, tags, body.slice(end));
|
|
263
|
+
}
|
|
264
|
+
case tag_codes_js_1.TagCode.DefineBinaryData: {
|
|
265
|
+
const id = r.u16();
|
|
266
|
+
const reserved = r.u32();
|
|
267
|
+
return new DefineBinaryDataTag(id, r.rest(), reserved);
|
|
268
|
+
}
|
|
269
|
+
case tag_codes_js_1.TagCode.Metadata: {
|
|
270
|
+
const xml = r.cstring();
|
|
271
|
+
if (!r.eof)
|
|
272
|
+
return new RawTag(code, body);
|
|
273
|
+
return new MetadataTag(xml);
|
|
274
|
+
}
|
|
275
|
+
case tag_codes_js_1.TagCode.FileAttributes:
|
|
276
|
+
if (body.length !== 4)
|
|
277
|
+
return new RawTag(code, body);
|
|
278
|
+
return new FileAttributesTag(r.u32());
|
|
279
|
+
default:
|
|
280
|
+
return new RawTag(code, body);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Reads a tag stream until (and including) the End tag or the end of data.
|
|
285
|
+
* Returns the tags and the offset right after the last consumed byte.
|
|
286
|
+
*/
|
|
287
|
+
function readTags(bytes, start, end) {
|
|
288
|
+
const r = new reader_js_1.ByteReader(bytes, start, end);
|
|
289
|
+
const tags = [];
|
|
290
|
+
while (r.remaining >= 2) {
|
|
291
|
+
const codeAndLength = r.u16();
|
|
292
|
+
const code = codeAndLength >> 6;
|
|
293
|
+
let length = codeAndLength & 0x3f;
|
|
294
|
+
const long = length === 0x3f;
|
|
295
|
+
if (long) {
|
|
296
|
+
if (r.remaining < 4)
|
|
297
|
+
break;
|
|
298
|
+
length = r.u32();
|
|
299
|
+
}
|
|
300
|
+
// Clamp truncated tags instead of failing the whole file.
|
|
301
|
+
const body = r.bytesView(Math.min(length, r.remaining)).slice();
|
|
302
|
+
let tag;
|
|
303
|
+
try {
|
|
304
|
+
tag = decodeTag(code, body);
|
|
305
|
+
}
|
|
306
|
+
catch {
|
|
307
|
+
tag = new RawTag(code, body);
|
|
308
|
+
}
|
|
309
|
+
tag.longHeader = long;
|
|
310
|
+
tags.push(tag);
|
|
311
|
+
if (code === tag_codes_js_1.TagCode.End)
|
|
312
|
+
break;
|
|
313
|
+
}
|
|
314
|
+
return { tags, end: r.pos };
|
|
315
|
+
}
|
|
316
|
+
function writeTag(w, tag) {
|
|
317
|
+
const body = tag.encodeBody();
|
|
318
|
+
if (body.length >= 0x3f || tag.longHeader) {
|
|
319
|
+
w.u16((tag.code << 6) | 0x3f);
|
|
320
|
+
w.u32(body.length);
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
w.u16((tag.code << 6) | body.length);
|
|
324
|
+
}
|
|
325
|
+
w.bytes(body);
|
|
326
|
+
}
|
|
327
|
+
function writeTags(w, tags) {
|
|
328
|
+
for (const t of tags)
|
|
329
|
+
writeTag(w, t);
|
|
330
|
+
}
|
package/dist/cli.d.ts
ADDED