sb-edit-custom 0.15.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.txt +9 -0
- package/README.md +0 -0
- package/lib/Block.d.ts +388 -0
- package/lib/Block.js +631 -0
- package/lib/BlockInput.d.ts +213 -0
- package/lib/BlockInput.js +3 -0
- package/lib/Costume.d.ts +25 -0
- package/lib/Costume.js +23 -0
- package/lib/Data.d.ts +50 -0
- package/lib/Data.js +44 -0
- package/lib/OpCode.d.ts +212 -0
- package/lib/OpCode.js +219 -0
- package/lib/Project.d.ts +29 -0
- package/lib/Project.js +66 -0
- package/lib/Script.d.ts +16 -0
- package/lib/Script.js +62 -0
- package/lib/Sound.d.ts +21 -0
- package/lib/Sound.js +21 -0
- package/lib/Target.d.ts +47 -0
- package/lib/Target.js +120 -0
- package/lib/cli/index.d.ts +2 -0
- package/lib/cli/index.js +511 -0
- package/lib/index.d.ts +10 -0
- package/lib/index.js +48 -0
- package/lib/io/leopard/toLeopard.d.ts +22 -0
- package/lib/io/leopard/toLeopard.js +2199 -0
- package/lib/io/sb2/fromSb2.d.ts +0 -0
- package/lib/io/sb2/fromSb2.js +2 -0
- package/lib/io/sb2/index.d.ts +48 -0
- package/lib/io/sb2/index.js +3 -0
- package/lib/io/sb2/toSb2.d.ts +0 -0
- package/lib/io/sb2/toSb2.js +2 -0
- package/lib/io/sb3/fromSb3.d.ts +16 -0
- package/lib/io/sb3/fromSb3.js +628 -0
- package/lib/io/sb3/interfaces.d.ts +624 -0
- package/lib/io/sb3/interfaces.js +336 -0
- package/lib/io/sb3/toSb3.d.ts +8 -0
- package/lib/io/sb3/toSb3.js +851 -0
- package/lib/io/scratchblocks/toScratchblocks.d.ts +7 -0
- package/lib/io/scratchblocks/toScratchblocks.js +606 -0
- package/lib/util/id.d.ts +1 -0
- package/lib/util/id.js +12 -0
- package/package.json +68 -0
|
@@ -0,0 +1,851 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
13
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
16
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
17
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
18
|
+
}
|
|
19
|
+
Object.defineProperty(o, k2, desc);
|
|
20
|
+
}) : (function(o, m, k, k2) {
|
|
21
|
+
if (k2 === undefined) k2 = k;
|
|
22
|
+
o[k2] = m[k];
|
|
23
|
+
}));
|
|
24
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
25
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
26
|
+
}) : function(o, v) {
|
|
27
|
+
o["default"] = v;
|
|
28
|
+
});
|
|
29
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
30
|
+
if (mod && mod.__esModule) return mod;
|
|
31
|
+
var result = {};
|
|
32
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
33
|
+
__setModuleDefault(result, mod);
|
|
34
|
+
return result;
|
|
35
|
+
};
|
|
36
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
37
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
38
|
+
if (ar || !(i in from)) {
|
|
39
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
40
|
+
ar[i] = from[i];
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
44
|
+
};
|
|
45
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
+
var Block_1 = require("../../Block");
|
|
47
|
+
var sb3 = __importStar(require("./interfaces"));
|
|
48
|
+
var OpCode_1 = require("../../OpCode");
|
|
49
|
+
var BIS = sb3.BlockInputStatus;
|
|
50
|
+
function toSb3(project, options) {
|
|
51
|
+
// Serialize a project. Returns an object containing the text to be stored
|
|
52
|
+
// in the caller's project.json output file. toSb3 should be bound or applied
|
|
53
|
+
// so that 'this' refers to the Project object to be serialized.
|
|
54
|
+
if (options === void 0) { options = {}; }
|
|
55
|
+
var warn = function () { return undefined; };
|
|
56
|
+
if (options.warn) {
|
|
57
|
+
warn = options.warn;
|
|
58
|
+
}
|
|
59
|
+
function serializeInputsToFields(inputs, fieldEntries) {
|
|
60
|
+
// Serialize provided inputs into a "fields" mapping that can be stored
|
|
61
|
+
// on a serialized block.
|
|
62
|
+
//
|
|
63
|
+
// Where the Scratch 3.0 term "input" refers to a slot that accepts blocks,
|
|
64
|
+
// the term "field" is any user-interactive slot that cannot be obscured as
|
|
65
|
+
// such. Fields are also the interactive element within any shadow block,
|
|
66
|
+
// making their presence key to nearly all inputs.
|
|
67
|
+
//
|
|
68
|
+
// While inputs are fairly complex to serialize, fields are comparatively
|
|
69
|
+
// simple. A field always contains only its selected or entered value, so
|
|
70
|
+
// it's not concerned with a variety of structures like an input is.
|
|
71
|
+
// The format for a field mapping looks something like this:
|
|
72
|
+
//
|
|
73
|
+
// {
|
|
74
|
+
// VARIABLE: ["my variable", "theVariablesId"]
|
|
75
|
+
// }
|
|
76
|
+
//
|
|
77
|
+
// Some fields take an ID; some don't. Here's another example:
|
|
78
|
+
//
|
|
79
|
+
// {
|
|
80
|
+
// DISTANCETOMENU: ["_mouse_"]
|
|
81
|
+
// }
|
|
82
|
+
//
|
|
83
|
+
// The important thing to remember with fields during serialization is that
|
|
84
|
+
// they refer to slots that don't accept blocks: non-droppable menus,
|
|
85
|
+
// primarily, but the value in a (non-compressed) shadow input too.
|
|
86
|
+
var fields = {};
|
|
87
|
+
if (!fieldEntries) {
|
|
88
|
+
return fields;
|
|
89
|
+
}
|
|
90
|
+
for (var _i = 0, _a = Object.keys(fieldEntries); _i < _a.length; _i++) {
|
|
91
|
+
var key = _a[_i];
|
|
92
|
+
// TODO: remove type assertion
|
|
93
|
+
var input = inputs[key];
|
|
94
|
+
// Fields are stored as a plain [value, id?] pair.
|
|
95
|
+
var valueOrName = void 0;
|
|
96
|
+
var id = void 0;
|
|
97
|
+
switch (input.type) {
|
|
98
|
+
case "variable":
|
|
99
|
+
case "list":
|
|
100
|
+
valueOrName = input.value.name;
|
|
101
|
+
id = input.value.id;
|
|
102
|
+
break;
|
|
103
|
+
default:
|
|
104
|
+
valueOrName = input.value;
|
|
105
|
+
id = null;
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
fields[key] = [valueOrName, id];
|
|
109
|
+
}
|
|
110
|
+
return fields;
|
|
111
|
+
}
|
|
112
|
+
function serializeInputShadow(value, options) {
|
|
113
|
+
// Serialize the shadow block representing a provided value and type.
|
|
114
|
+
//
|
|
115
|
+
// To gather an understanding of what shadow blocks are used for, have
|
|
116
|
+
// a look at serializeInputsToInputs; the gist is that they represent the
|
|
117
|
+
// actual place in which you type a value or select an option from a
|
|
118
|
+
// dropdown menu, and they can be obscured by having a block placed in
|
|
119
|
+
// their place.
|
|
120
|
+
//
|
|
121
|
+
// A shadow block's only concerns are with revealing an interactive field
|
|
122
|
+
// to the user. They exist so that inputs can let a non-shadow block stand
|
|
123
|
+
// in place of that field.
|
|
124
|
+
//
|
|
125
|
+
// There are two forms in which a shadow block can be serialized. The rarer
|
|
126
|
+
// structure, though the more basic one, is simply that of a typical block,
|
|
127
|
+
// only with the "shadow: true" flag set. A shadow block contains a single
|
|
128
|
+
// field; this field is stored the same as in any non-shadow block. Such a
|
|
129
|
+
// serialized shadow block might look like this:
|
|
130
|
+
//
|
|
131
|
+
// {
|
|
132
|
+
// opcode: "math_number",
|
|
133
|
+
// shadow: true,
|
|
134
|
+
// parent: "someBlockId",
|
|
135
|
+
// fields: {
|
|
136
|
+
// NUM: [50]
|
|
137
|
+
// }
|
|
138
|
+
// }
|
|
139
|
+
//
|
|
140
|
+
// The second form contains essentially the same data, but in a more
|
|
141
|
+
// "compressed" form. In this form, the shadow block is stored as a simple
|
|
142
|
+
// [type, value] pair, where the type is a constant representing the opcode
|
|
143
|
+
// and field name in which the value should be placed when deserializing.
|
|
144
|
+
// Because it's so much more concise than the non-compressed form, most
|
|
145
|
+
// inputs are serialized in this way. The same input above in compressed
|
|
146
|
+
// form would look like this:
|
|
147
|
+
//
|
|
148
|
+
// [4, 50]
|
|
149
|
+
//
|
|
150
|
+
// As described in serializeInputsToInputs, compressed shadow blocks are
|
|
151
|
+
// stored inline with the input they correspond to, not as separate blocks
|
|
152
|
+
// with IDs.
|
|
153
|
+
//
|
|
154
|
+
// Within this code, we use the primimtiveOrOpCode option to determine how
|
|
155
|
+
// the shadow should be serialized. If it is a number, it's referring to a
|
|
156
|
+
// "primitive", the term uses for shadows when they are in the compressed
|
|
157
|
+
// form. If it's a string, it is a (shadow) block opcode, and should be
|
|
158
|
+
// serialized in the expanded form.
|
|
159
|
+
var _a;
|
|
160
|
+
var blockData = options.blockData, parentId = options.parentId, primitiveOrOpCode = options.primitiveOrOpCode, shadowId = options.shadowId;
|
|
161
|
+
var shadowValue = null;
|
|
162
|
+
if (primitiveOrOpCode === BIS.BROADCAST_PRIMITIVE) {
|
|
163
|
+
// Broadcast primitives, unlike all other primitives, expect two values:
|
|
164
|
+
// the broadcast name and its ID. We just reuse the name for its ID;
|
|
165
|
+
// after all, the name is the unique identifier sb-edit uses to refer to
|
|
166
|
+
// the broadcast.
|
|
167
|
+
shadowValue = [BIS.BROADCAST_PRIMITIVE, value, value];
|
|
168
|
+
}
|
|
169
|
+
else if (primitiveOrOpCode === BIS.COLOR_PICKER_PRIMITIVE) {
|
|
170
|
+
// Color primitive. Convert the {r, g, b} object into hex form.
|
|
171
|
+
// TODO: remove type assertion and actually check if the value is an RGB literal
|
|
172
|
+
var hex = function (k) {
|
|
173
|
+
return (value || { r: 0, g: 0, b: 0 })[k].toString(16).padStart(2, "0");
|
|
174
|
+
};
|
|
175
|
+
shadowValue = [BIS.COLOR_PICKER_PRIMITIVE, "#" + hex("r") + hex("g") + hex("b")];
|
|
176
|
+
}
|
|
177
|
+
else if (typeof primitiveOrOpCode === "number") {
|
|
178
|
+
// Primitive shadow, can be stored in compressed form.
|
|
179
|
+
shadowValue = [primitiveOrOpCode, String(value)];
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
// Note: Only 1-field shadow blocks are supported.
|
|
183
|
+
var shadowOpCode = primitiveOrOpCode;
|
|
184
|
+
var fieldEntries = sb3.fieldTypeMap[shadowOpCode];
|
|
185
|
+
if (fieldEntries) {
|
|
186
|
+
var fieldKey = Object.keys(fieldEntries)[0];
|
|
187
|
+
var fields = (_a = {}, _a[fieldKey] = [value], _a);
|
|
188
|
+
blockData[shadowId] = {
|
|
189
|
+
opcode: shadowOpCode,
|
|
190
|
+
next: null,
|
|
191
|
+
parent: parentId,
|
|
192
|
+
fields: fields,
|
|
193
|
+
inputs: {},
|
|
194
|
+
mutation: undefined,
|
|
195
|
+
shadow: true,
|
|
196
|
+
topLevel: false
|
|
197
|
+
};
|
|
198
|
+
shadowValue = shadowId;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return shadowValue;
|
|
202
|
+
}
|
|
203
|
+
function serializeInputsToInputs(inputs, options) {
|
|
204
|
+
// Serialize provided inputs into an "inputs" mapping that can be stored
|
|
205
|
+
// on a serialized block.
|
|
206
|
+
//
|
|
207
|
+
// In any Scratch block, the majority of behavior configuration is provided
|
|
208
|
+
// by setting values for fields and inputs. In Scratch 3.0, the term
|
|
209
|
+
// "input" refers to any slot in a block where a block may be placed.
|
|
210
|
+
// (Fields are slots which don't accept blocks - non-droppable dropdown
|
|
211
|
+
// menus, most of the time.)
|
|
212
|
+
//
|
|
213
|
+
// During serialization, there are three fundamental ways to describe an
|
|
214
|
+
// input, each associated with a particular constant numeral. They're all
|
|
215
|
+
// based on the concept of a "shadow block", which is a representation of
|
|
216
|
+
// the non-block contents of an input. They're described in the following
|
|
217
|
+
// list, and are detailed further in serializeInputShadow.
|
|
218
|
+
//
|
|
219
|
+
// (1) INPUT_SAME_BLOCK_SHADOW:
|
|
220
|
+
// The input contains only a shadow block - no non-shadow. Take the
|
|
221
|
+
// number input (612), for example. The element you type in to change
|
|
222
|
+
// that value is the shadow block. Because there is nothing obscuring
|
|
223
|
+
// the shadow block, the input is serialized as INPUT_SAME_BLOCK_SHADOW.
|
|
224
|
+
// (2) INPUT_BLOCK_NO_SHADOW:
|
|
225
|
+
// The input contains a non-shadow block - but no shadow. These are
|
|
226
|
+
// relatively rare, since most inputs contain a shadow block (even when
|
|
227
|
+
// obscured - see (3) below). Examples of inputs that don't are boolean
|
|
228
|
+
// and substack slots, both prominent in blocks in the Control category.
|
|
229
|
+
// (3) INPUT_DIFF_BLOCK_SHADOW:
|
|
230
|
+
// The input contains a non-shadow block - and a shadow block, too.
|
|
231
|
+
// This is the case when you've placed an ordinary Scratch block into the
|
|
232
|
+
// input, obscuring the shadow block in its place. It's worth noting that
|
|
233
|
+
// Scratch 3.0 remembers the type and value of an obscured shadow: if you
|
|
234
|
+
// place a block ((4) * (13)) into that number input (612), and later
|
|
235
|
+
// remove it, Scratch will reveal the (612) shadow again.
|
|
236
|
+
//
|
|
237
|
+
// There is one other way an input may be serialized, which is simply not
|
|
238
|
+
// storing it at all. This occurs when an input contains neither a shadow
|
|
239
|
+
// nor a non-shadow, as in INPUT_BLOCK_NO_SHADOW (2) but with the block
|
|
240
|
+
// removed. (It's technically also valid to output null as the ID of the
|
|
241
|
+
// block inside an INPUT_BLOCK_NO_SHADOW to represent such inputs. In this
|
|
242
|
+
// code we choose not to store them at all.)
|
|
243
|
+
//
|
|
244
|
+
// When all is said and done, a block's inputs are stored as a mapping of
|
|
245
|
+
// each input's ID to an array whose first item is one of the constants
|
|
246
|
+
// described above, and whose following items depend on which constant.
|
|
247
|
+
// For the block "go to x: (50) y: ((x position) of (dog))", that mapping
|
|
248
|
+
// might look something like this:
|
|
249
|
+
//
|
|
250
|
+
// inputs: {
|
|
251
|
+
// X: [INPUT_SAME_BLOCK_SHADOW, [4, 50]],
|
|
252
|
+
// Y: [INPUT_DIFF_BLOCK_SHADOW, "some block id", [4, -50]]
|
|
253
|
+
// }
|
|
254
|
+
//
|
|
255
|
+
// The arrays [4, 50] and [4, -50] represent the two shadow blocks these
|
|
256
|
+
// inputs hold (the latter obscured by the "of" block). The value 4 is a
|
|
257
|
+
// constant referring to a "math_number" - essentially, it is the type of
|
|
258
|
+
// the shadow contained within that input.
|
|
259
|
+
//
|
|
260
|
+
// It's worth noting that some shadows are serialized as
|
|
261
|
+
// actual blocks on the target's "blocks" dictionary, and referred to by
|
|
262
|
+
// ID; the inputs in "switch to costume (item (random) of (costumes))"
|
|
263
|
+
// follow this structure:
|
|
264
|
+
//
|
|
265
|
+
// inputs: {
|
|
266
|
+
// COSTUME: [INPUT_DIFF_BLOCK_SHADOW, "id 1", "id 2"]
|
|
267
|
+
// }
|
|
268
|
+
//
|
|
269
|
+
// ...where id 2 is the ID of the obscured shadow block. Specific details
|
|
270
|
+
// on how shadow blocks are serialized and whether they're stored as
|
|
271
|
+
// arrays or referenced by block ID is described in serializeInputShadow.
|
|
272
|
+
// As far as the input mapping is concerned, all that matters is that the
|
|
273
|
+
// two formats may be interchanged with one another.
|
|
274
|
+
//
|
|
275
|
+
// Also note that there are a couple blocks (specifically the variable and
|
|
276
|
+
// list-contents getters) which are serialized altogether in the compressed
|
|
277
|
+
// much the same as a compressed shadow, irregardless of the type of the
|
|
278
|
+
// input they've been placed inside. This is because they're so common in
|
|
279
|
+
// a project, and do not have any inputs of their own - only a field to
|
|
280
|
+
// identify which variable or list the block corresponds to. The input
|
|
281
|
+
// mapping for the block "set x to (spawn x)" would look something like
|
|
282
|
+
// this:
|
|
283
|
+
//
|
|
284
|
+
// inputs: {
|
|
285
|
+
// X: [INPUT_DIFF_BLOCK_SHADOW, [12, "spawn x", "someId"], [4, 0]]
|
|
286
|
+
// }
|
|
287
|
+
//
|
|
288
|
+
// ...where someId is the ID of the variable, and [4, 0] is the obscured
|
|
289
|
+
// shadow block, as usual.
|
|
290
|
+
var block = options.block, blockData = options.blockData, initialBroadcastName = options.initialBroadcastName, customBlockDataMap = options.customBlockDataMap, initialValues = options.initialValues, inputEntries = options.inputEntries, target = options.target;
|
|
291
|
+
var resultInputs = {};
|
|
292
|
+
for (var _i = 0, _a = Object.entries(inputEntries); _i < _a.length; _i++) {
|
|
293
|
+
var _b = _a[_i], key = _b[0], entry = _b[1];
|
|
294
|
+
var input = inputs[key];
|
|
295
|
+
if (entry === sb3.BooleanOrSubstackInputStatus) {
|
|
296
|
+
var blockId = null;
|
|
297
|
+
if (input) {
|
|
298
|
+
var options_1 = {
|
|
299
|
+
target: target,
|
|
300
|
+
blockData: blockData,
|
|
301
|
+
initialBroadcastName: initialBroadcastName,
|
|
302
|
+
customBlockDataMap: customBlockDataMap,
|
|
303
|
+
parent: block
|
|
304
|
+
};
|
|
305
|
+
switch (input.type) {
|
|
306
|
+
case "blocks":
|
|
307
|
+
if (input.value !== null)
|
|
308
|
+
blockId = serializeBlockStack(input.value, options_1);
|
|
309
|
+
break;
|
|
310
|
+
case "block":
|
|
311
|
+
blockId = serializeBlock(input.value, options_1);
|
|
312
|
+
break;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
if (blockId) {
|
|
316
|
+
resultInputs[key] = [BIS.INPUT_BLOCK_NO_SHADOW, blockId];
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
else {
|
|
320
|
+
var valueForShadow = void 0;
|
|
321
|
+
if (input.type === "block") {
|
|
322
|
+
valueForShadow = initialValues[key];
|
|
323
|
+
// Special-case some input opcodes for more realistic initial values.
|
|
324
|
+
switch (entry) {
|
|
325
|
+
case OpCode_1.OpCode.looks_costume:
|
|
326
|
+
if (target.costumes[0]) {
|
|
327
|
+
valueForShadow = target.costumes[0].name;
|
|
328
|
+
}
|
|
329
|
+
break;
|
|
330
|
+
case OpCode_1.OpCode.sound_sounds_menu:
|
|
331
|
+
if (target.sounds[0]) {
|
|
332
|
+
valueForShadow = target.sounds[0].name;
|
|
333
|
+
}
|
|
334
|
+
break;
|
|
335
|
+
case OpCode_1.OpCode.event_broadcast_menu:
|
|
336
|
+
valueForShadow = initialBroadcastName;
|
|
337
|
+
break;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
else {
|
|
341
|
+
valueForShadow = input.value;
|
|
342
|
+
}
|
|
343
|
+
var shadowValue = serializeInputShadow(valueForShadow, {
|
|
344
|
+
blockData: blockData,
|
|
345
|
+
parentId: block.id,
|
|
346
|
+
shadowId: block.id + "-" + key,
|
|
347
|
+
primitiveOrOpCode: entry
|
|
348
|
+
});
|
|
349
|
+
if (input.type === "block") {
|
|
350
|
+
var obscuringBlockValue = void 0;
|
|
351
|
+
switch (input.value.opcode) {
|
|
352
|
+
case OpCode_1.OpCode.data_variable: {
|
|
353
|
+
var _c = input.value.inputs.VARIABLE.value, variableId = _c.id, variableName = _c.name;
|
|
354
|
+
obscuringBlockValue = [BIS.VAR_PRIMITIVE, variableName, variableId];
|
|
355
|
+
break;
|
|
356
|
+
}
|
|
357
|
+
case OpCode_1.OpCode.data_listcontents: {
|
|
358
|
+
var _d = input.value.inputs.LIST.value, listId = _d.id, listName = _d.name;
|
|
359
|
+
obscuringBlockValue = [BIS.LIST_PRIMITIVE, listName, listId];
|
|
360
|
+
break;
|
|
361
|
+
}
|
|
362
|
+
default: {
|
|
363
|
+
obscuringBlockValue = serializeBlock(input.value, {
|
|
364
|
+
blockData: blockData,
|
|
365
|
+
initialBroadcastName: initialBroadcastName,
|
|
366
|
+
customBlockDataMap: customBlockDataMap,
|
|
367
|
+
parent: block,
|
|
368
|
+
target: target
|
|
369
|
+
});
|
|
370
|
+
break;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
if (shadowValue) {
|
|
374
|
+
resultInputs[key] = [BIS.INPUT_DIFF_BLOCK_SHADOW, obscuringBlockValue, shadowValue];
|
|
375
|
+
}
|
|
376
|
+
else {
|
|
377
|
+
resultInputs[key] = [BIS.INPUT_BLOCK_NO_SHADOW, obscuringBlockValue];
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
else {
|
|
381
|
+
resultInputs[key] = [BIS.INPUT_SAME_BLOCK_SHADOW, shadowValue];
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
return resultInputs;
|
|
386
|
+
}
|
|
387
|
+
function serializeInputs(block, options) {
|
|
388
|
+
// Serialize a block's inputs, returning the data which should be stored on
|
|
389
|
+
// the serialized block, as well as any associated blockData.
|
|
390
|
+
//
|
|
391
|
+
// This function looks more intimidating than it ought to; most of the meat
|
|
392
|
+
// here is related to serializing specific blocks whose resultant data must
|
|
393
|
+
// be generated differently than other blocks. (Custom blocks are related
|
|
394
|
+
// the main ones to blame.)
|
|
395
|
+
//
|
|
396
|
+
// serializeInputs is in charge of converting the inputs on the provided
|
|
397
|
+
// block into the structures that Scratch 3.0 expects. There are (usually)
|
|
398
|
+
// two mappings into which inputs are stored: fields and inputs. Specific
|
|
399
|
+
// details on how these are serialized is discussed in their corresponding
|
|
400
|
+
// functions (which serializeInputs defers to for most blocks), but the
|
|
401
|
+
// gist is:
|
|
402
|
+
//
|
|
403
|
+
// * Fields store actual data, while inputs refer to shadow blocks.
|
|
404
|
+
// (Each shadow block contains a field for storing the value of that
|
|
405
|
+
// input, though often they are serialized as a "compressed" form that
|
|
406
|
+
// doesn't explicitly label that field. See serializeInputsToInputs.)
|
|
407
|
+
// * Reporter blocks can be placed only into inputs - not fields.
|
|
408
|
+
// (In actuality, the input is not replaced by a block; rather, the way
|
|
409
|
+
// it is stored is changed to refer to the ID of the placed block, and
|
|
410
|
+
// the shadow block contianing the field value is maintained, "obscured"
|
|
411
|
+
// but able to be recovered if the obscuring block is moved elsewhere.)
|
|
412
|
+
//
|
|
413
|
+
// Blocks may also have a "mutation" field. This is an XML attribute
|
|
414
|
+
// mapping containing data specific to a particular instance of a block
|
|
415
|
+
// that wouldn't fit on the block's input and field mappings. Specific
|
|
416
|
+
// details may vary greatly based on the opcode.
|
|
417
|
+
var blockData = options.blockData, target = options.target, initialBroadcastName = options.initialBroadcastName, customBlockDataMap = options.customBlockDataMap;
|
|
418
|
+
var fields = serializeInputsToFields(block.inputs, sb3.fieldTypeMap[block.opcode]);
|
|
419
|
+
var inputs = {};
|
|
420
|
+
var mutation;
|
|
421
|
+
if (block.isKnownBlock()) {
|
|
422
|
+
switch (block.opcode) {
|
|
423
|
+
case OpCode_1.OpCode.procedures_definition: {
|
|
424
|
+
var prototypeId = block.id + "-prototype";
|
|
425
|
+
var _a = customBlockDataMap[block.inputs.PROCCODE.value], args = _a.args, warp = _a.warp;
|
|
426
|
+
var prototypeInputs = {};
|
|
427
|
+
for (var _i = 0, args_1 = args; _i < args_1.length; _i++) {
|
|
428
|
+
var arg = args_1[_i];
|
|
429
|
+
var shadowId = arg.id + "-prototype-shadow";
|
|
430
|
+
blockData[shadowId] = {
|
|
431
|
+
opcode: {
|
|
432
|
+
boolean: OpCode_1.OpCode.argument_reporter_boolean,
|
|
433
|
+
numberOrString: OpCode_1.OpCode.argument_reporter_string_number
|
|
434
|
+
}[arg.type],
|
|
435
|
+
next: null,
|
|
436
|
+
parent: prototypeId,
|
|
437
|
+
inputs: {},
|
|
438
|
+
fields: {
|
|
439
|
+
VALUE: [arg.name]
|
|
440
|
+
},
|
|
441
|
+
mutation: undefined,
|
|
442
|
+
shadow: true,
|
|
443
|
+
topLevel: false
|
|
444
|
+
};
|
|
445
|
+
prototypeInputs[arg.id] = [BIS.INPUT_SAME_BLOCK_SHADOW, shadowId];
|
|
446
|
+
}
|
|
447
|
+
blockData[prototypeId] = {
|
|
448
|
+
opcode: OpCode_1.OpCode.procedures_prototype,
|
|
449
|
+
next: null,
|
|
450
|
+
parent: block.id,
|
|
451
|
+
inputs: prototypeInputs,
|
|
452
|
+
fields: {},
|
|
453
|
+
shadow: true,
|
|
454
|
+
topLevel: false,
|
|
455
|
+
mutation: {
|
|
456
|
+
tagName: "mutation",
|
|
457
|
+
children: [],
|
|
458
|
+
proccode: block.inputs.PROCCODE.value,
|
|
459
|
+
argumentids: JSON.stringify(args.map(function (arg) { return arg.id; })),
|
|
460
|
+
argumentnames: JSON.stringify(args.map(function (arg) { return arg.name; })),
|
|
461
|
+
argumentdefaults: JSON.stringify(args.map(function (arg) { return arg.default; })),
|
|
462
|
+
warp: JSON.stringify(warp)
|
|
463
|
+
}
|
|
464
|
+
};
|
|
465
|
+
inputs.custom_block = [BIS.INPUT_SAME_BLOCK_SHADOW, prototypeId];
|
|
466
|
+
break;
|
|
467
|
+
}
|
|
468
|
+
case OpCode_1.OpCode.procedures_call: {
|
|
469
|
+
var proccode = block.inputs.PROCCODE.value;
|
|
470
|
+
var customBlockData = customBlockDataMap[proccode];
|
|
471
|
+
if (!customBlockData) {
|
|
472
|
+
warn("Missing custom block prototype for proccode ".concat(proccode, " (").concat(block.id, " in ").concat(target.name, "); skipping this block"));
|
|
473
|
+
return null;
|
|
474
|
+
}
|
|
475
|
+
var args = customBlockData.args, warp = customBlockData.warp;
|
|
476
|
+
mutation = {
|
|
477
|
+
tagName: "mutation",
|
|
478
|
+
children: [],
|
|
479
|
+
proccode: proccode,
|
|
480
|
+
argumentids: JSON.stringify(args.map(function (arg) { return arg.id; })),
|
|
481
|
+
warp: JSON.stringify(warp)
|
|
482
|
+
};
|
|
483
|
+
var inputEntries = {};
|
|
484
|
+
var constructedInputs = {};
|
|
485
|
+
var initialValues = {};
|
|
486
|
+
for (var i = 0; i < args.length; i++) {
|
|
487
|
+
var _b = args[i], type = _b.type, id = _b.id;
|
|
488
|
+
switch (type) {
|
|
489
|
+
case "boolean":
|
|
490
|
+
inputEntries[id] = sb3.BooleanOrSubstackInputStatus;
|
|
491
|
+
// A boolean input's initialValues entry will never be
|
|
492
|
+
// referenced (because empty boolean inputs don't contain
|
|
493
|
+
// shadow blocks), so there's no need to set it.
|
|
494
|
+
break;
|
|
495
|
+
case "numberOrString":
|
|
496
|
+
inputEntries[id] = BIS.TEXT_PRIMITIVE;
|
|
497
|
+
initialValues[id] = "";
|
|
498
|
+
break;
|
|
499
|
+
}
|
|
500
|
+
constructedInputs[id] = block.inputs.INPUTS.value[i];
|
|
501
|
+
}
|
|
502
|
+
inputs = serializeInputsToInputs(constructedInputs, {
|
|
503
|
+
target: target,
|
|
504
|
+
blockData: blockData,
|
|
505
|
+
initialBroadcastName: initialBroadcastName,
|
|
506
|
+
customBlockDataMap: customBlockDataMap,
|
|
507
|
+
block: block,
|
|
508
|
+
initialValues: initialValues,
|
|
509
|
+
inputEntries: inputEntries
|
|
510
|
+
});
|
|
511
|
+
break;
|
|
512
|
+
}
|
|
513
|
+
default: {
|
|
514
|
+
var inputEntries = sb3.inputPrimitiveOrShadowMap[block.opcode];
|
|
515
|
+
var initialValues = {};
|
|
516
|
+
for (var _c = 0, _d = Object.keys(inputEntries); _c < _d.length; _c++) {
|
|
517
|
+
var key = _d[_c];
|
|
518
|
+
var defaultInput = Block_1.BlockBase.getDefaultInput(block.opcode, key);
|
|
519
|
+
if (defaultInput) {
|
|
520
|
+
initialValues[key] = defaultInput.initial;
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
inputs = serializeInputsToInputs(block.inputs, {
|
|
524
|
+
target: target,
|
|
525
|
+
blockData: blockData,
|
|
526
|
+
initialBroadcastName: initialBroadcastName,
|
|
527
|
+
customBlockDataMap: customBlockDataMap,
|
|
528
|
+
block: block,
|
|
529
|
+
initialValues: initialValues,
|
|
530
|
+
inputEntries: inputEntries
|
|
531
|
+
});
|
|
532
|
+
break;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
return { inputs: inputs, fields: fields, mutation: mutation };
|
|
537
|
+
}
|
|
538
|
+
function serializeBlock(block, options) {
|
|
539
|
+
// Serialize a block, mutating the passed block data and returning the
|
|
540
|
+
// ID which should be used when referring to this block, or null if no
|
|
541
|
+
// such block could be serialized.
|
|
542
|
+
//
|
|
543
|
+
// As discussed in serializeTarget, blocks are serialized into a single
|
|
544
|
+
// flat dictionary (per target), rather than an abstract syntax tree.
|
|
545
|
+
// Within a serialized block, it's common to find reference to another
|
|
546
|
+
// block by its ID. This is seen in linking to the next and parent blocks,
|
|
547
|
+
// and to inputs.
|
|
548
|
+
//
|
|
549
|
+
// In Scratch 3.0 (contrasting with 2.0 as well as the intermediate format
|
|
550
|
+
// created for sb-edit), "inputs" are stored in not one but two containers
|
|
551
|
+
// per block: inputs, and fields. The difference is discussed in their
|
|
552
|
+
// corresponding functions. Blocks may also carry a mutation, a mapping of
|
|
553
|
+
// XML property names and values, for use in some blocks (notably those
|
|
554
|
+
// associated with custom blocks). All this data is serialized and detailed
|
|
555
|
+
// in serializeInputs.
|
|
556
|
+
//
|
|
557
|
+
// serializeBlock is in charge of serializing an individual block, as well
|
|
558
|
+
// as its following block, and building the links between it and its parent
|
|
559
|
+
// and siblings. As with other block-related functions, data is collected
|
|
560
|
+
// into a flat mapping of IDs to their associated serialized block.
|
|
561
|
+
//
|
|
562
|
+
// It's possible for a block to be skipped altogether during serialization,
|
|
563
|
+
// because it referred to some value which could not be converted into
|
|
564
|
+
// valid SB3 data. For reporters, this means leaving an empty input; for
|
|
565
|
+
// stack blocks, it means skipping to the next block in the sibling array
|
|
566
|
+
// (or leaving an empty connection if there is none). It's up to the caller
|
|
567
|
+
// to handle serializeBlock returning a null blockId usefully.
|
|
568
|
+
//
|
|
569
|
+
// Note that while serializeBlock will recursively serialize input blocks,
|
|
570
|
+
// it will not serialize the following sibling block. As such, the
|
|
571
|
+
// serialized block will always contain {next: null}. The caller is
|
|
572
|
+
// responsible for updating this and setting it to the following block ID.
|
|
573
|
+
// (The function serializeBlockStack is generally where this happens.)
|
|
574
|
+
var blockData = options.blockData, initialBroadcastName = options.initialBroadcastName, customBlockDataMap = options.customBlockDataMap, parent = options.parent, target = options.target;
|
|
575
|
+
var serializeInputsResult = serializeInputs(block, {
|
|
576
|
+
target: target,
|
|
577
|
+
blockData: blockData,
|
|
578
|
+
initialBroadcastName: initialBroadcastName,
|
|
579
|
+
customBlockDataMap: customBlockDataMap
|
|
580
|
+
});
|
|
581
|
+
if (!serializeInputsResult) {
|
|
582
|
+
return null;
|
|
583
|
+
}
|
|
584
|
+
var inputs = serializeInputsResult.inputs, fields = serializeInputsResult.fields, mutation = serializeInputsResult.mutation;
|
|
585
|
+
var obj = {
|
|
586
|
+
opcode: block.opcode,
|
|
587
|
+
parent: parent ? parent.id : null,
|
|
588
|
+
next: null,
|
|
589
|
+
topLevel: !parent,
|
|
590
|
+
inputs: inputs,
|
|
591
|
+
fields: fields,
|
|
592
|
+
mutation: mutation,
|
|
593
|
+
shadow: false
|
|
594
|
+
};
|
|
595
|
+
if (obj.topLevel) {
|
|
596
|
+
obj.x = options.x;
|
|
597
|
+
obj.y = options.y;
|
|
598
|
+
}
|
|
599
|
+
var blockId = block.id;
|
|
600
|
+
blockData[blockId] = obj;
|
|
601
|
+
return blockId;
|
|
602
|
+
}
|
|
603
|
+
function serializeBlockStack(blocks, options) {
|
|
604
|
+
// Serialize a stack of blocks, returning the ID of the first successfully
|
|
605
|
+
// serialized block, or null if there is none.
|
|
606
|
+
//
|
|
607
|
+
// When serializing a block returns null, there is an expectation that the
|
|
608
|
+
// block should be "skipped" by the caller. When dealing with stack blocks,
|
|
609
|
+
// that means making a connection between the previous block and the first
|
|
610
|
+
// successfully successfully serialized following block. This function
|
|
611
|
+
// handles that case, as well as building the connections between stack
|
|
612
|
+
// blocks in general.
|
|
613
|
+
//
|
|
614
|
+
// Note that the passed options object will be mutated, to change the
|
|
615
|
+
// parent block to the previous block in the stack.
|
|
616
|
+
var blockData = options.blockData;
|
|
617
|
+
var previousBlockId = null;
|
|
618
|
+
var firstBlockId = null;
|
|
619
|
+
for (var _i = 0, blocks_1 = blocks; _i < blocks_1.length; _i++) {
|
|
620
|
+
var block = blocks_1[_i];
|
|
621
|
+
var blockId = serializeBlock(block, options);
|
|
622
|
+
if (!blockId) {
|
|
623
|
+
continue;
|
|
624
|
+
}
|
|
625
|
+
if (!firstBlockId) {
|
|
626
|
+
firstBlockId = blockId;
|
|
627
|
+
}
|
|
628
|
+
if (previousBlockId) {
|
|
629
|
+
blockData[previousBlockId].next = blockId;
|
|
630
|
+
}
|
|
631
|
+
previousBlockId = blockId;
|
|
632
|
+
options.parent = block;
|
|
633
|
+
}
|
|
634
|
+
return firstBlockId;
|
|
635
|
+
}
|
|
636
|
+
function collectCustomBlockData(target) {
|
|
637
|
+
// Parse the scripts in a target, collecting metadata about each custom
|
|
638
|
+
// block's arguments and other info, and return a mapping of proccode to
|
|
639
|
+
// the associated data.
|
|
640
|
+
//
|
|
641
|
+
// It's necesary to collect this data prior to serializing any associated
|
|
642
|
+
// procedures_call blocks, because they require access to data only found
|
|
643
|
+
// on the associated procedures_definition. (Specifically, the types of
|
|
644
|
+
// each input on the custom block, since those will influence the initial
|
|
645
|
+
// value & shadow type in the serialized caller block's inputs.)
|
|
646
|
+
var data = {};
|
|
647
|
+
for (var _i = 0, _a = target.scripts; _i < _a.length; _i++) {
|
|
648
|
+
var script = _a[_i];
|
|
649
|
+
var block = script.blocks[0];
|
|
650
|
+
if (block.opcode !== OpCode_1.OpCode.procedures_definition) {
|
|
651
|
+
continue;
|
|
652
|
+
}
|
|
653
|
+
var proccode = block.inputs.PROCCODE.value;
|
|
654
|
+
var warp = block.inputs.WARP.value;
|
|
655
|
+
var args = [];
|
|
656
|
+
var argData = block.inputs.ARGUMENTS.value;
|
|
657
|
+
for (var i = 0; i < argData.length; i++) {
|
|
658
|
+
var _b = argData[i], name_1 = _b.name, type = _b.type;
|
|
659
|
+
if (type === "label") {
|
|
660
|
+
continue;
|
|
661
|
+
}
|
|
662
|
+
var id = "".concat(block.id, "-argument-").concat(i);
|
|
663
|
+
args.push({
|
|
664
|
+
id: id,
|
|
665
|
+
name: name_1,
|
|
666
|
+
type: type,
|
|
667
|
+
default: {
|
|
668
|
+
boolean: "false",
|
|
669
|
+
numberOrString: ""
|
|
670
|
+
}[type]
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
data[proccode] = { args: args, warp: warp };
|
|
674
|
+
}
|
|
675
|
+
return data;
|
|
676
|
+
}
|
|
677
|
+
function serializeTarget(target, options) {
|
|
678
|
+
// Serialize a target. This function typically isn't used on its own, in
|
|
679
|
+
// favor of the specialized functions for sprites and stage. It contains
|
|
680
|
+
// the base code shared across all targets - sounds and costumes, variables
|
|
681
|
+
// and lists, and, of course, blocks, for example.
|
|
682
|
+
//
|
|
683
|
+
// In Scratch 3.0, the representation for the code in a sprite is a flat,
|
|
684
|
+
// one-dimensional mapping of block ID to block data. To identify which
|
|
685
|
+
// blocks are the first block in a "script", a topLevel flag is used.
|
|
686
|
+
// This differs considerably from 2.0, where the scripts property of any
|
|
687
|
+
// target contained an AST (abstract syntax tree) representation.
|
|
688
|
+
//
|
|
689
|
+
// When a block is serialized, a flat block mapping is returned, and this
|
|
690
|
+
// is combined into the mapping of whatever is consuming the serialized
|
|
691
|
+
// data. Eventually, all blocks (and their subblocks, inputs, etc) have
|
|
692
|
+
// been serialized, and the collected data is stored on the target.
|
|
693
|
+
//
|
|
694
|
+
// serializeTarget also handles converting costumes, sounds, variables,
|
|
695
|
+
// etc into the structures Scratch 3.0 expects.
|
|
696
|
+
function mapToIdObject(values, fn) {
|
|
697
|
+
// Map an Array of objects with an "id` property
|
|
698
|
+
// (e.g [{id: 1, prop: "val"}, ...])
|
|
699
|
+
// into an object whose keys are the `id` property,
|
|
700
|
+
// and whose values are the passed objects transformed by `fn`.
|
|
701
|
+
var ret = {};
|
|
702
|
+
for (var _i = 0, values_1 = values; _i < values_1.length; _i++) {
|
|
703
|
+
var object = values_1[_i];
|
|
704
|
+
ret[object.id] = fn(object);
|
|
705
|
+
}
|
|
706
|
+
return ret;
|
|
707
|
+
}
|
|
708
|
+
var broadcasts = options.broadcasts, initialBroadcastName = options.initialBroadcastName;
|
|
709
|
+
var blockData = {};
|
|
710
|
+
var customBlockDataMap = collectCustomBlockData(target);
|
|
711
|
+
for (var _i = 0, _a = target.scripts; _i < _a.length; _i++) {
|
|
712
|
+
var script = _a[_i];
|
|
713
|
+
serializeBlockStack(script.blocks, {
|
|
714
|
+
target: target,
|
|
715
|
+
blockData: blockData,
|
|
716
|
+
initialBroadcastName: initialBroadcastName,
|
|
717
|
+
customBlockDataMap: customBlockDataMap,
|
|
718
|
+
x: script.x,
|
|
719
|
+
y: script.y
|
|
720
|
+
});
|
|
721
|
+
}
|
|
722
|
+
return {
|
|
723
|
+
name: target.name,
|
|
724
|
+
isStage: target.isStage,
|
|
725
|
+
currentCostume: target.costumeNumber,
|
|
726
|
+
layerOrder: target.layerOrder,
|
|
727
|
+
volume: target.volume,
|
|
728
|
+
blocks: blockData,
|
|
729
|
+
broadcasts: broadcasts,
|
|
730
|
+
// @todo sb-edit doesn't support comments (as of feb 12, 2020)
|
|
731
|
+
comments: {},
|
|
732
|
+
sounds: target.sounds.map(function (sound) {
|
|
733
|
+
var _a, _b;
|
|
734
|
+
return ({
|
|
735
|
+
name: sound.name,
|
|
736
|
+
dataFormat: sound.ext,
|
|
737
|
+
assetId: sound.md5,
|
|
738
|
+
md5ext: sound.md5 + "." + sound.ext,
|
|
739
|
+
sampleCount: (_a = sound.sampleCount) !== null && _a !== void 0 ? _a : undefined,
|
|
740
|
+
rate: (_b = sound.sampleRate) !== null && _b !== void 0 ? _b : undefined
|
|
741
|
+
});
|
|
742
|
+
}),
|
|
743
|
+
costumes: target.costumes.map(function (costume) {
|
|
744
|
+
var _a, _b;
|
|
745
|
+
return ({
|
|
746
|
+
name: costume.name,
|
|
747
|
+
assetId: costume.md5,
|
|
748
|
+
md5ext: costume.md5 + "." + costume.ext,
|
|
749
|
+
bitmapResolution: costume.bitmapResolution,
|
|
750
|
+
dataFormat: costume.ext,
|
|
751
|
+
rotationCenterX: (_a = costume.centerX) !== null && _a !== void 0 ? _a : undefined,
|
|
752
|
+
rotationCenterY: (_b = costume.centerY) !== null && _b !== void 0 ? _b : undefined
|
|
753
|
+
});
|
|
754
|
+
}),
|
|
755
|
+
variables: mapToIdObject(target.variables, function (_a) {
|
|
756
|
+
var name = _a.name, value = _a.value, cloud = _a.cloud;
|
|
757
|
+
if (cloud) {
|
|
758
|
+
return [name, value, cloud];
|
|
759
|
+
}
|
|
760
|
+
else {
|
|
761
|
+
return [name, value];
|
|
762
|
+
}
|
|
763
|
+
}),
|
|
764
|
+
lists: mapToIdObject(target.lists, function (_a) {
|
|
765
|
+
var name = _a.name, value = _a.value;
|
|
766
|
+
return [name, value];
|
|
767
|
+
})
|
|
768
|
+
};
|
|
769
|
+
}
|
|
770
|
+
var rotationStyleMap = {
|
|
771
|
+
normal: "all around",
|
|
772
|
+
leftRight: "left-right",
|
|
773
|
+
none: "don't rotate"
|
|
774
|
+
};
|
|
775
|
+
function serializeSprite(sprite, options) {
|
|
776
|
+
// Serialize a sprite. Extending from a serialized target, sprites carry
|
|
777
|
+
// a variety of properties for their on-screen position and appearance.
|
|
778
|
+
var initialBroadcastName = options.initialBroadcastName;
|
|
779
|
+
return __assign(__assign({}, serializeTarget(sprite, {
|
|
780
|
+
initialBroadcastName: initialBroadcastName,
|
|
781
|
+
// Broadcasts are stored on the stage, not on any sprite.
|
|
782
|
+
broadcasts: {}
|
|
783
|
+
})), { isStage: false, x: sprite.x, y: sprite.y, size: sprite.size, direction: sprite.direction, rotationStyle: rotationStyleMap[sprite.rotationStyle], draggable: sprite.isDraggable, visible: sprite.visible });
|
|
784
|
+
}
|
|
785
|
+
function serializeStage(stage, options) {
|
|
786
|
+
// Serialize a stage. Extending from a serialized target, the stage carries
|
|
787
|
+
// additional properties for values shared across the project - notably,
|
|
788
|
+
// the broadcast dictionary, as well as values for some extensions.
|
|
789
|
+
var broadcasts = options.broadcasts, initialBroadcastName = options.initialBroadcastName;
|
|
790
|
+
return __assign(__assign({}, serializeTarget(stage, { broadcasts: broadcasts, initialBroadcastName: initialBroadcastName })), { isStage: true, tempo: options.tempo, textToSpeechLanguage: options.textToSpeechLanguage, videoState: options.videoState, videoTransparency: options.videoTransparency });
|
|
791
|
+
}
|
|
792
|
+
function serializeProject(project) {
|
|
793
|
+
// Serialize a project. This is the master function used when project.toSb3
|
|
794
|
+
// is called. The main purpose of serializeProject is to serialize each
|
|
795
|
+
// target (sprite or stage) and collect them together in the final output
|
|
796
|
+
// format. It also provides utility functions shared across every target's
|
|
797
|
+
// serialization, e.g. broadcast utilities.
|
|
798
|
+
// Set the broadcast name used in obscured broadcast inputs to the first
|
|
799
|
+
// sorted-alphabetically broadcast's name. While we're parsing through
|
|
800
|
+
// all the broadcast names in the project, also store them on a simple
|
|
801
|
+
// mapping of (name -> name), to be stored on the stage. (toSb3 uses a
|
|
802
|
+
// broadcast's name as its ID.)
|
|
803
|
+
var lowestName;
|
|
804
|
+
var broadcasts = {};
|
|
805
|
+
for (var _i = 0, _a = __spreadArray([project.stage], project.sprites, true); _i < _a.length; _i++) {
|
|
806
|
+
var target = _a[_i];
|
|
807
|
+
for (var _b = 0, _c = target.blocks; _b < _c.length; _b++) {
|
|
808
|
+
var block = _c[_b];
|
|
809
|
+
if (block.opcode === OpCode_1.OpCode.event_whenbroadcastreceived ||
|
|
810
|
+
block.opcode === OpCode_1.OpCode.event_broadcast ||
|
|
811
|
+
block.opcode === OpCode_1.OpCode.event_broadcastandwait) {
|
|
812
|
+
var broadcastInput = block.opcode === OpCode_1.OpCode.event_whenbroadcastreceived
|
|
813
|
+
? block.inputs.BROADCAST_OPTION
|
|
814
|
+
: block.inputs.BROADCAST_INPUT;
|
|
815
|
+
if (broadcastInput.type === "broadcast") {
|
|
816
|
+
var currentName = broadcastInput.value;
|
|
817
|
+
if (typeof lowestName === "undefined" || currentName < lowestName) {
|
|
818
|
+
lowestName = currentName;
|
|
819
|
+
}
|
|
820
|
+
broadcasts[currentName] = currentName;
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
var initialBroadcastName = lowestName || "message1";
|
|
826
|
+
return {
|
|
827
|
+
targets: __spreadArray([
|
|
828
|
+
serializeStage(project.stage, {
|
|
829
|
+
initialBroadcastName: initialBroadcastName,
|
|
830
|
+
broadcasts: broadcasts,
|
|
831
|
+
tempo: project.tempo,
|
|
832
|
+
textToSpeechLanguage: project.textToSpeechLanguage,
|
|
833
|
+
videoState: project.videoOn ? "on" : "off",
|
|
834
|
+
videoTransparency: project.videoAlpha
|
|
835
|
+
})
|
|
836
|
+
], project.sprites.map(function (sprite) {
|
|
837
|
+
return serializeSprite(sprite, {
|
|
838
|
+
initialBroadcastName: initialBroadcastName
|
|
839
|
+
});
|
|
840
|
+
}), true),
|
|
841
|
+
meta: {
|
|
842
|
+
semver: "3.0.0"
|
|
843
|
+
}
|
|
844
|
+
};
|
|
845
|
+
}
|
|
846
|
+
return {
|
|
847
|
+
json: JSON.stringify(serializeProject(project))
|
|
848
|
+
};
|
|
849
|
+
}
|
|
850
|
+
exports.default = toSb3;
|
|
851
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9TYjMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvaW8vc2IzL3RvU2IzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHFDQUErQztBQUkvQyxnREFBb0M7QUFDcEMsdUNBQXNDO0FBRXRDLElBQU0sR0FBRyxHQUFHLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQztBQVVqQyxTQUF3QixLQUFLLENBQUMsT0FBZ0IsRUFBRSxPQUFtQztJQUNqRiwwRUFBMEU7SUFDMUUsNkVBQTZFO0lBQzdFLGdFQUFnRTtJQUhsQix3QkFBQSxFQUFBLFlBQW1DO0lBS2pGLElBQUksSUFBSSxHQUF5QixjQUFZLE9BQUEsU0FBUyxFQUFULENBQVMsQ0FBQztJQUN2RCxJQUFJLE9BQU8sQ0FBQyxJQUFJLEVBQUU7UUFDaEIsSUFBSSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUM7S0FDckI7SUFFRCxTQUFTLHVCQUF1QixDQUM5QixNQUF5QyxFQUN6QyxZQUErQztRQUUvQyx1RUFBdUU7UUFDdkUseUJBQXlCO1FBQ3pCLEVBQUU7UUFDRiwyRUFBMkU7UUFDM0UsMkVBQTJFO1FBQzNFLHlFQUF5RTtRQUN6RSxrREFBa0Q7UUFDbEQsRUFBRTtRQUNGLHlFQUF5RTtRQUN6RSx5RUFBeUU7UUFDekUsb0VBQW9FO1FBQ3BFLDREQUE0RDtRQUM1RCxFQUFFO1FBQ0YsTUFBTTtRQUNOLGtEQUFrRDtRQUNsRCxNQUFNO1FBQ04sRUFBRTtRQUNGLDhEQUE4RDtRQUM5RCxFQUFFO1FBQ0YsTUFBTTtRQUNOLGtDQUFrQztRQUNsQyxNQUFNO1FBQ04sRUFBRTtRQUNGLDJFQUEyRTtRQUMzRSxxRUFBcUU7UUFDckUsbUVBQW1FO1FBRW5FLElBQU0sTUFBTSxHQUF3QixFQUFFLENBQUM7UUFFdkMsSUFBSSxDQUFDLFlBQVksRUFBRTtZQUNqQixPQUFPLE1BQU0sQ0FBQztTQUNmO1FB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
|