ae-agent-setup 0.2.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/CSXS/manifest.xml +44 -0
- package/README.ja.md +249 -0
- package/README.md +249 -0
- package/bin/ae-agent-setup.mjs +337 -0
- package/client/CSInterface.js +1291 -0
- package/client/index.html +64 -0
- package/client/lib/bridge_utils.js +56 -0
- package/client/lib/logging.js +10 -0
- package/client/lib/request_handlers.js +468 -0
- package/client/lib/request_handlers_essential.js +35 -0
- package/client/lib/request_handlers_layer_structure.js +180 -0
- package/client/lib/request_handlers_scene.js +38 -0
- package/client/lib/request_handlers_shape.js +288 -0
- package/client/lib/request_handlers_timeline.js +115 -0
- package/client/lib/runtime.js +35 -0
- package/client/lib/server.js +33 -0
- package/client/main.js +1 -0
- package/host/index.jsx +11 -0
- package/host/json2.js +504 -0
- package/host/lib/common.jsx +128 -0
- package/host/lib/mutation_handlers.jsx +358 -0
- package/host/lib/mutation_keyframe_handlers.jsx +265 -0
- package/host/lib/mutation_layer_structure_handlers.jsx +235 -0
- package/host/lib/mutation_scene_handlers.jsx +1226 -0
- package/host/lib/mutation_shape_handlers.jsx +358 -0
- package/host/lib/mutation_timeline_handlers.jsx +137 -0
- package/host/lib/property_utils.jsx +105 -0
- package/host/lib/query_handlers.jsx +427 -0
- package/package.json +21 -0
- package/scripts/signing/build-zxp.sh +56 -0
- package/scripts/signing/create-dev-cert.sh +97 -0
- package/scripts/signing/install-zxp.sh +29 -0
- package/templates/skills/aftereffects-cli.SKILL.md +74 -0
- package/templates/skills/aftereffects-declarative.SKILL.md +112 -0
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
function addShapeRepeater(layerId, layerName, optionsJSON) {
|
|
2
|
+
try {
|
|
3
|
+
ensureJSON();
|
|
4
|
+
var comp = app.project.activeItem;
|
|
5
|
+
var resolvedLayer = aeResolveLayer(comp, layerId, layerName);
|
|
6
|
+
if (resolvedLayer.error) {
|
|
7
|
+
return encodePayload({ status: "error", message: resolvedLayer.error });
|
|
8
|
+
}
|
|
9
|
+
var layer = resolvedLayer.layer;
|
|
10
|
+
if (layer.matchName !== "ADBE Vector Layer") {
|
|
11
|
+
return encodePayload({ status: "error", message: "Target layer is not a shape layer." });
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
var options = {};
|
|
15
|
+
if (optionsJSON && optionsJSON !== "null") {
|
|
16
|
+
try {
|
|
17
|
+
options = JSON.parse(optionsJSON);
|
|
18
|
+
} catch (eParse) {
|
|
19
|
+
return encodePayload({ status: "error", message: "Invalid options JSON: " + eParse.toString() });
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function clamp(value, minValue, maxValue) {
|
|
24
|
+
if (value < minValue) {
|
|
25
|
+
return minValue;
|
|
26
|
+
}
|
|
27
|
+
if (value > maxValue) {
|
|
28
|
+
return maxValue;
|
|
29
|
+
}
|
|
30
|
+
return value;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function toNumberOrNull(value) {
|
|
34
|
+
if (value === null || value === undefined) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
var num = Number(value);
|
|
38
|
+
if (isNaN(num)) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
return num;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function toVec2(value) {
|
|
45
|
+
if (!(value instanceof Array) || value.length !== 2) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
var x = Number(value[0]);
|
|
49
|
+
var y = Number(value[1]);
|
|
50
|
+
if (isNaN(x) || isNaN(y)) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
return [x, y];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
var rootVectors = layer.property("ADBE Root Vectors Group");
|
|
57
|
+
if (!rootVectors) {
|
|
58
|
+
return encodePayload({ status: "error", message: "Shape contents not found." });
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
var groupIndex = parseInt(options.groupIndex, 10);
|
|
62
|
+
if (isNaN(groupIndex) || groupIndex <= 0) {
|
|
63
|
+
groupIndex = 1;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
var targetGroup = rootVectors.property(groupIndex);
|
|
67
|
+
if (!targetGroup || targetGroup.matchName !== "ADBE Vector Group") {
|
|
68
|
+
return encodePayload({ status: "error", message: "Shape group not found at groupIndex " + groupIndex + "." });
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
var contents = targetGroup.property("ADBE Vectors Group");
|
|
72
|
+
if (!contents) {
|
|
73
|
+
return encodePayload({ status: "error", message: "Shape group contents not found." });
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
var repeater = contents.addProperty("ADBE Vector Filter - Repeater");
|
|
77
|
+
if (!repeater) {
|
|
78
|
+
return encodePayload({ status: "error", message: "Failed to add Repeater." });
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (options.name && String(options.name).length > 0) {
|
|
82
|
+
repeater.name = String(options.name);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
var copies = toNumberOrNull(options.copies);
|
|
86
|
+
if (copies !== null) {
|
|
87
|
+
if (copies < 0) {
|
|
88
|
+
copies = 0;
|
|
89
|
+
}
|
|
90
|
+
repeater.property("ADBE Vector Repeater Copies").setValue(copies);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
var offset = toNumberOrNull(options.offset);
|
|
94
|
+
if (offset !== null) {
|
|
95
|
+
repeater.property("ADBE Vector Repeater Offset").setValue(offset);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
var transform = repeater.property("ADBE Vector Repeater Transform");
|
|
99
|
+
if (transform) {
|
|
100
|
+
var position = toVec2(options.position);
|
|
101
|
+
if (position) {
|
|
102
|
+
transform.property("ADBE Vector Repeater Position").setValue(position);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
var scale = toVec2(options.scale);
|
|
106
|
+
if (scale) {
|
|
107
|
+
transform.property("ADBE Vector Repeater Scale").setValue(scale);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
var rotation = toNumberOrNull(options.rotation);
|
|
111
|
+
if (rotation !== null) {
|
|
112
|
+
transform.property("ADBE Vector Repeater Rotation").setValue(rotation);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
var startOpacity = toNumberOrNull(options.startOpacity);
|
|
116
|
+
if (startOpacity !== null) {
|
|
117
|
+
transform.property("ADBE Vector Repeater Opacity 1").setValue(clamp(startOpacity, 0, 100));
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
var endOpacity = toNumberOrNull(options.endOpacity);
|
|
121
|
+
if (endOpacity !== null) {
|
|
122
|
+
transform.property("ADBE Vector Repeater Opacity 2").setValue(clamp(endOpacity, 0, 100));
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return encodePayload({
|
|
127
|
+
status: "success",
|
|
128
|
+
layerId: layer.index,
|
|
129
|
+
layerUid: aeTryGetLayerUid(layer),
|
|
130
|
+
layerName: layer.name,
|
|
131
|
+
groupIndex: groupIndex,
|
|
132
|
+
repeaterName: repeater.name
|
|
133
|
+
});
|
|
134
|
+
} catch (e) {
|
|
135
|
+
log("addShapeRepeater() threw: " + e.toString());
|
|
136
|
+
return encodePayload({ status: "error", message: e.toString() });
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function addLayer(layerType, optionsJSON) {
|
|
141
|
+
try {
|
|
142
|
+
ensureJSON();
|
|
143
|
+
var comp = app.project.activeItem;
|
|
144
|
+
if (!comp || !(comp instanceof CompItem)) {
|
|
145
|
+
return encodePayload({ status: "error", message: "Active composition not found." });
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
var requestedType = (layerType || "null").toString().toLowerCase();
|
|
149
|
+
var options = {};
|
|
150
|
+
if (optionsJSON && optionsJSON !== "null") {
|
|
151
|
+
try {
|
|
152
|
+
options = JSON.parse(optionsJSON);
|
|
153
|
+
} catch (eParse) {
|
|
154
|
+
return encodePayload({ status: "error", message: "Invalid options JSON: " + eParse.toString() });
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function getNumber(value, fallback) {
|
|
159
|
+
if (value === null || value === undefined) {
|
|
160
|
+
return fallback;
|
|
161
|
+
}
|
|
162
|
+
var parsed = Number(value);
|
|
163
|
+
if (isNaN(parsed)) {
|
|
164
|
+
return fallback;
|
|
165
|
+
}
|
|
166
|
+
return parsed;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function toColor01(value, fallback) {
|
|
170
|
+
if (!(value instanceof Array) || value.length !== 3) {
|
|
171
|
+
return fallback;
|
|
172
|
+
}
|
|
173
|
+
var color = [];
|
|
174
|
+
for (var i = 0; i < 3; i++) {
|
|
175
|
+
var part = Number(value[i]);
|
|
176
|
+
if (isNaN(part)) {
|
|
177
|
+
return fallback;
|
|
178
|
+
}
|
|
179
|
+
if (part > 1) {
|
|
180
|
+
part = part / 255;
|
|
181
|
+
}
|
|
182
|
+
if (part < 0) {
|
|
183
|
+
part = 0;
|
|
184
|
+
}
|
|
185
|
+
if (part > 1) {
|
|
186
|
+
part = 1;
|
|
187
|
+
}
|
|
188
|
+
color.push(part);
|
|
189
|
+
}
|
|
190
|
+
return color;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function clamp(value, minValue, maxValue) {
|
|
194
|
+
if (value < minValue) {
|
|
195
|
+
return minValue;
|
|
196
|
+
}
|
|
197
|
+
if (value > maxValue) {
|
|
198
|
+
return maxValue;
|
|
199
|
+
}
|
|
200
|
+
return value;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function toVec2(value, fallback) {
|
|
204
|
+
if (!(value instanceof Array) || value.length !== 2) {
|
|
205
|
+
return fallback;
|
|
206
|
+
}
|
|
207
|
+
var first = Number(value[0]);
|
|
208
|
+
var second = Number(value[1]);
|
|
209
|
+
if (isNaN(first) || isNaN(second)) {
|
|
210
|
+
return fallback;
|
|
211
|
+
}
|
|
212
|
+
return [first, second];
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function toLineCapValue(value) {
|
|
216
|
+
var normalized = value === null || value === undefined ? "" : String(value).toLowerCase();
|
|
217
|
+
if (normalized === "round") {
|
|
218
|
+
return 2;
|
|
219
|
+
}
|
|
220
|
+
if (normalized === "projecting") {
|
|
221
|
+
return 3;
|
|
222
|
+
}
|
|
223
|
+
return 1;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
var layer = null;
|
|
227
|
+
var name = options.name && options.name.length > 0 ? options.name : null;
|
|
228
|
+
var createdShapeType = null;
|
|
229
|
+
|
|
230
|
+
if (requestedType === "text") {
|
|
231
|
+
var text = options.text;
|
|
232
|
+
if (text === null || text === undefined) {
|
|
233
|
+
text = "";
|
|
234
|
+
}
|
|
235
|
+
layer = comp.layers.addText(String(text));
|
|
236
|
+
} else if (requestedType === "null") {
|
|
237
|
+
layer = comp.layers.addNull();
|
|
238
|
+
} else if (requestedType === "shape") {
|
|
239
|
+
layer = comp.layers.addShape();
|
|
240
|
+
var rootVectors = layer.property("ADBE Root Vectors Group");
|
|
241
|
+
if (!rootVectors) {
|
|
242
|
+
return encodePayload({ status: "error", message: "Shape root vectors not found." });
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
var vectorGroup = rootVectors.addProperty("ADBE Vector Group");
|
|
246
|
+
if (!vectorGroup) {
|
|
247
|
+
return encodePayload({ status: "error", message: "Failed to create shape vector group." });
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
var groupContents = vectorGroup.property("ADBE Vectors Group");
|
|
251
|
+
if (!groupContents) {
|
|
252
|
+
return encodePayload({ status: "error", message: "Failed to access shape group contents." });
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
var shapeType = options.shapeType ? String(options.shapeType).toLowerCase() : "ellipse";
|
|
256
|
+
if (shapeType !== "ellipse" && shapeType !== "rect") {
|
|
257
|
+
shapeType = "ellipse";
|
|
258
|
+
}
|
|
259
|
+
createdShapeType = shapeType;
|
|
260
|
+
|
|
261
|
+
var shapeSize = toVec2(options.shapeSize, [Math.round(comp.width * 0.25), Math.round(comp.width * 0.25)]);
|
|
262
|
+
if (shapeSize[0] <= 0) {
|
|
263
|
+
shapeSize[0] = 1;
|
|
264
|
+
}
|
|
265
|
+
if (shapeSize[1] <= 0) {
|
|
266
|
+
shapeSize[1] = 1;
|
|
267
|
+
}
|
|
268
|
+
var shapePosition = toVec2(options.shapePosition, [0, 0]);
|
|
269
|
+
|
|
270
|
+
if (shapeType === "rect") {
|
|
271
|
+
vectorGroup.name = "Rect";
|
|
272
|
+
var rectPath = groupContents.addProperty("ADBE Vector Shape - Rect");
|
|
273
|
+
if (!rectPath) {
|
|
274
|
+
return encodePayload({ status: "error", message: "Failed to create rectangle shape." });
|
|
275
|
+
}
|
|
276
|
+
rectPath.property("ADBE Vector Rect Size").setValue(shapeSize);
|
|
277
|
+
rectPath.property("ADBE Vector Rect Position").setValue(shapePosition);
|
|
278
|
+
var roundness = getNumber(options.shapeRoundness, 0);
|
|
279
|
+
if (roundness < 0) {
|
|
280
|
+
roundness = 0;
|
|
281
|
+
}
|
|
282
|
+
rectPath.property("ADBE Vector Rect Roundness").setValue(roundness);
|
|
283
|
+
} else {
|
|
284
|
+
vectorGroup.name = "Ellipse";
|
|
285
|
+
var ellipsePath = groupContents.addProperty("ADBE Vector Shape - Ellipse");
|
|
286
|
+
if (!ellipsePath) {
|
|
287
|
+
return encodePayload({ status: "error", message: "Failed to create ellipse shape." });
|
|
288
|
+
}
|
|
289
|
+
ellipsePath.property("ADBE Vector Ellipse Size").setValue(shapeSize);
|
|
290
|
+
ellipsePath.property("ADBE Vector Ellipse Position").setValue(shapePosition);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
var fill = groupContents.addProperty("ADBE Vector Graphic - Fill");
|
|
294
|
+
if (fill) {
|
|
295
|
+
var fillColor = toColor01(options.shapeFillColor, [1, 1, 1]);
|
|
296
|
+
var fillOpacity = clamp(getNumber(options.shapeFillOpacity, 100), 0, 100);
|
|
297
|
+
fill.property("ADBE Vector Fill Color").setValue(fillColor);
|
|
298
|
+
fill.property("ADBE Vector Fill Opacity").setValue(fillOpacity);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
var shouldAddStroke =
|
|
302
|
+
options.shapeStrokeColor !== undefined ||
|
|
303
|
+
options.shapeStrokeOpacity !== undefined ||
|
|
304
|
+
options.shapeStrokeWidth !== undefined ||
|
|
305
|
+
options.shapeStrokeLineCap !== undefined;
|
|
306
|
+
if (shouldAddStroke) {
|
|
307
|
+
var stroke = groupContents.addProperty("ADBE Vector Graphic - Stroke");
|
|
308
|
+
if (stroke) {
|
|
309
|
+
var strokeColor = toColor01(options.shapeStrokeColor, [1, 1, 1]);
|
|
310
|
+
var strokeOpacity = clamp(getNumber(options.shapeStrokeOpacity, 100), 0, 100);
|
|
311
|
+
var strokeWidth = getNumber(options.shapeStrokeWidth, 4);
|
|
312
|
+
if (strokeWidth < 0) {
|
|
313
|
+
strokeWidth = 0;
|
|
314
|
+
}
|
|
315
|
+
stroke.property("ADBE Vector Stroke Color").setValue(strokeColor);
|
|
316
|
+
stroke.property("ADBE Vector Stroke Opacity").setValue(strokeOpacity);
|
|
317
|
+
stroke.property("ADBE Vector Stroke Width").setValue(strokeWidth);
|
|
318
|
+
stroke.property("ADBE Vector Stroke Line Cap").setValue(toLineCapValue(options.shapeStrokeLineCap));
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
} else if (requestedType === "solid") {
|
|
322
|
+
var solidName = name || "Solid";
|
|
323
|
+
var solidColor = toColor01(options.color, [0.5, 0.5, 0.5]);
|
|
324
|
+
var solidWidth = Math.max(1, Math.round(getNumber(options.width, comp.width)));
|
|
325
|
+
var solidHeight = Math.max(1, Math.round(getNumber(options.height, comp.height)));
|
|
326
|
+
var solidDuration = getNumber(options.duration, comp.duration);
|
|
327
|
+
if (solidDuration <= 0) {
|
|
328
|
+
solidDuration = comp.duration;
|
|
329
|
+
}
|
|
330
|
+
layer = comp.layers.addSolid(solidColor, solidName, solidWidth, solidHeight, 1.0, solidDuration);
|
|
331
|
+
} else {
|
|
332
|
+
return encodePayload({
|
|
333
|
+
status: "error",
|
|
334
|
+
message: "Unsupported layerType. Use one of: text, null, solid, shape."
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
if (!layer) {
|
|
339
|
+
return encodePayload({ status: "error", message: "Failed to add layer." });
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
if (name && requestedType !== "solid") {
|
|
343
|
+
layer.name = name;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
return encodePayload({
|
|
347
|
+
status: "success",
|
|
348
|
+
layerId: layer.index,
|
|
349
|
+
layerUid: aeTryGetLayerUid(layer),
|
|
350
|
+
layerName: layer.name,
|
|
351
|
+
layerType: getLayerTypeName(layer),
|
|
352
|
+
shapeType: createdShapeType
|
|
353
|
+
});
|
|
354
|
+
} catch (e) {
|
|
355
|
+
log("addLayer() threw: " + e.toString());
|
|
356
|
+
return encodePayload({ status: "error", message: e.toString() });
|
|
357
|
+
}
|
|
358
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
function setInOutPoint(layerId, layerName, inPoint, outPoint) {
|
|
2
|
+
try {
|
|
3
|
+
ensureJSON();
|
|
4
|
+
var comp = app.project.activeItem;
|
|
5
|
+
var resolvedLayer = aeResolveLayer(comp, layerId, layerName);
|
|
6
|
+
if (resolvedLayer.error) {
|
|
7
|
+
return encodePayload({ status: "error", message: resolvedLayer.error });
|
|
8
|
+
}
|
|
9
|
+
var layer = resolvedLayer.layer;
|
|
10
|
+
|
|
11
|
+
var hasIn = inPoint !== null && inPoint !== undefined;
|
|
12
|
+
var hasOut = outPoint !== null && outPoint !== undefined;
|
|
13
|
+
if (!hasIn && !hasOut) {
|
|
14
|
+
return encodePayload({ status: "error", message: "At least one of inPoint/outPoint is required." });
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
var nextIn = hasIn ? Number(inPoint) : Number(layer.inPoint);
|
|
18
|
+
var nextOut = hasOut ? Number(outPoint) : Number(layer.outPoint);
|
|
19
|
+
if (isNaN(nextIn) || isNaN(nextOut)) {
|
|
20
|
+
return encodePayload({ status: "error", message: "inPoint/outPoint must be numeric." });
|
|
21
|
+
}
|
|
22
|
+
if (nextOut < nextIn) {
|
|
23
|
+
return encodePayload({ status: "error", message: "outPoint must be greater than or equal to inPoint." });
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (hasIn) {
|
|
27
|
+
layer.inPoint = nextIn;
|
|
28
|
+
}
|
|
29
|
+
if (hasOut) {
|
|
30
|
+
layer.outPoint = nextOut;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return encodePayload({
|
|
34
|
+
status: "success",
|
|
35
|
+
layerId: layer.index,
|
|
36
|
+
layerUid: aeTryGetLayerUid(layer),
|
|
37
|
+
layerName: layer.name,
|
|
38
|
+
inPoint: layer.inPoint,
|
|
39
|
+
outPoint: layer.outPoint
|
|
40
|
+
});
|
|
41
|
+
} catch (e) {
|
|
42
|
+
log("setInOutPoint() threw: " + e.toString());
|
|
43
|
+
return encodePayload({ status: "error", message: e.toString() });
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function moveLayerTime(layerId, layerName, delta) {
|
|
48
|
+
try {
|
|
49
|
+
ensureJSON();
|
|
50
|
+
var comp = app.project.activeItem;
|
|
51
|
+
var resolvedLayer = aeResolveLayer(comp, layerId, layerName);
|
|
52
|
+
if (resolvedLayer.error) {
|
|
53
|
+
return encodePayload({ status: "error", message: resolvedLayer.error });
|
|
54
|
+
}
|
|
55
|
+
var layer = resolvedLayer.layer;
|
|
56
|
+
|
|
57
|
+
var deltaValue = Number(delta);
|
|
58
|
+
if (isNaN(deltaValue)) {
|
|
59
|
+
return encodePayload({ status: "error", message: "delta must be a number." });
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
layer.startTime = layer.startTime + deltaValue;
|
|
63
|
+
|
|
64
|
+
return encodePayload({
|
|
65
|
+
status: "success",
|
|
66
|
+
layerId: layer.index,
|
|
67
|
+
layerUid: aeTryGetLayerUid(layer),
|
|
68
|
+
layerName: layer.name,
|
|
69
|
+
startTime: layer.startTime,
|
|
70
|
+
inPoint: layer.inPoint,
|
|
71
|
+
outPoint: layer.outPoint
|
|
72
|
+
});
|
|
73
|
+
} catch (e) {
|
|
74
|
+
log("moveLayerTime() threw: " + e.toString());
|
|
75
|
+
return encodePayload({ status: "error", message: e.toString() });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function setCTI(time) {
|
|
80
|
+
try {
|
|
81
|
+
ensureJSON();
|
|
82
|
+
var comp = app.project.activeItem;
|
|
83
|
+
if (!comp || !(comp instanceof CompItem)) {
|
|
84
|
+
return encodePayload({ status: "error", message: "Active composition not found." });
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
var timeValue = Number(time);
|
|
88
|
+
if (isNaN(timeValue)) {
|
|
89
|
+
return encodePayload({ status: "error", message: "time must be a number." });
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
comp.time = timeValue;
|
|
93
|
+
|
|
94
|
+
return encodePayload({
|
|
95
|
+
status: "success",
|
|
96
|
+
compId: comp.id,
|
|
97
|
+
compName: comp.name,
|
|
98
|
+
time: comp.time
|
|
99
|
+
});
|
|
100
|
+
} catch (e) {
|
|
101
|
+
log("setCTI() threw: " + e.toString());
|
|
102
|
+
return encodePayload({ status: "error", message: e.toString() });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function setWorkArea(start, duration) {
|
|
107
|
+
try {
|
|
108
|
+
ensureJSON();
|
|
109
|
+
var comp = app.project.activeItem;
|
|
110
|
+
if (!comp || !(comp instanceof CompItem)) {
|
|
111
|
+
return encodePayload({ status: "error", message: "Active composition not found." });
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
var startValue = Number(start);
|
|
115
|
+
var durationValue = Number(duration);
|
|
116
|
+
if (isNaN(startValue) || isNaN(durationValue)) {
|
|
117
|
+
return encodePayload({ status: "error", message: "start and duration must be numbers." });
|
|
118
|
+
}
|
|
119
|
+
if (durationValue < 0) {
|
|
120
|
+
return encodePayload({ status: "error", message: "duration must be greater than or equal to 0." });
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
comp.workAreaStart = startValue;
|
|
124
|
+
comp.workAreaDuration = durationValue;
|
|
125
|
+
|
|
126
|
+
return encodePayload({
|
|
127
|
+
status: "success",
|
|
128
|
+
compId: comp.id,
|
|
129
|
+
compName: comp.name,
|
|
130
|
+
start: comp.workAreaStart,
|
|
131
|
+
duration: comp.workAreaDuration
|
|
132
|
+
});
|
|
133
|
+
} catch (e) {
|
|
134
|
+
log("setWorkArea() threw: " + e.toString());
|
|
135
|
+
return encodePayload({ status: "error", message: e.toString() });
|
|
136
|
+
}
|
|
137
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
var AE_PROPERTY_TYPE_PROPERTY = 6212;
|
|
2
|
+
var AE_PROPERTY_TYPE_GROUP = 6213;
|
|
3
|
+
|
|
4
|
+
function aePropertyValueToString(prop) {
|
|
5
|
+
try {
|
|
6
|
+
var value = prop.value;
|
|
7
|
+
if (value === null || value === undefined) {
|
|
8
|
+
return "";
|
|
9
|
+
}
|
|
10
|
+
if (value instanceof Array) {
|
|
11
|
+
return value.join(", ");
|
|
12
|
+
}
|
|
13
|
+
if (typeof value === "boolean") {
|
|
14
|
+
return value ? "true" : "false";
|
|
15
|
+
}
|
|
16
|
+
return value.toString();
|
|
17
|
+
} catch (e) {
|
|
18
|
+
return "";
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function aeCanTraverseProperty(prop) {
|
|
23
|
+
if (!prop) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
if (prop.propertyType === AE_PROPERTY_TYPE_GROUP) {
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
} catch (e) {}
|
|
31
|
+
return typeof prop.numProperties === "number" && prop.numProperties > 0;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function aeIsPropertyNode(prop) {
|
|
35
|
+
if (!prop) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
if (prop.propertyType === AE_PROPERTY_TYPE_PROPERTY) {
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
} catch (e) {}
|
|
43
|
+
return !aeCanTraverseProperty(prop);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function aeIsEnabledProperty(prop) {
|
|
47
|
+
if (!prop) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
if (typeof prop.enabled === "boolean") {
|
|
52
|
+
return prop.enabled;
|
|
53
|
+
}
|
|
54
|
+
} catch (e) {}
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function aeCanExposeProperty(prop) {
|
|
59
|
+
if (!aeIsEnabledProperty(prop)) {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
if (prop.canSetExpression === false) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
if (prop.canSetExpression === true) {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
} catch (e) {}
|
|
70
|
+
try {
|
|
71
|
+
if (typeof prop.canSetValue === "boolean") {
|
|
72
|
+
return prop.canSetValue;
|
|
73
|
+
}
|
|
74
|
+
} catch (e2) {}
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function aeArrayContains(arr, value) {
|
|
79
|
+
if (!arr || !value) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
for (var i = 0; i < arr.length; i++) {
|
|
83
|
+
if (arr[i] === value) {
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function aeGetPropertyIdentifier(prop, fallbackIndex) {
|
|
91
|
+
try {
|
|
92
|
+
if (prop.matchName && prop.matchName.length > 0) {
|
|
93
|
+
return prop.matchName;
|
|
94
|
+
}
|
|
95
|
+
} catch (e) {}
|
|
96
|
+
try {
|
|
97
|
+
if (prop.name && prop.name.length > 0) {
|
|
98
|
+
return prop.name;
|
|
99
|
+
}
|
|
100
|
+
} catch (e2) {}
|
|
101
|
+
if (typeof fallbackIndex === "number") {
|
|
102
|
+
return "Property_" + fallbackIndex;
|
|
103
|
+
}
|
|
104
|
+
return "Property";
|
|
105
|
+
}
|