@popcraft/cli 0.53.0 → 0.53.2
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/dist/popcraft.mjs +357 -173
- package/package.json +2 -2
package/dist/popcraft.mjs
CHANGED
|
@@ -1196,7 +1196,7 @@ function operations(spec = openapi) {
|
|
|
1196
1196
|
}
|
|
1197
1197
|
async function call(target2, method, path, opts = {}) {
|
|
1198
1198
|
const qs = new URLSearchParams(opts.query ?? {}).toString();
|
|
1199
|
-
const headers = { "user-agent": `popcraft-cli/${"0.53.
|
|
1199
|
+
const headers = { "user-agent": `popcraft-cli/${"0.53.2"}`, ...opts.headers };
|
|
1200
1200
|
if (target2.token) headers.authorization = `Bearer ${target2.token}`;
|
|
1201
1201
|
if (opts.contentType) headers["content-type"] = opts.contentType;
|
|
1202
1202
|
try {
|
|
@@ -6786,8 +6786,8 @@ function currentPrintPage(doc2, pageId2, o = {}) {
|
|
|
6786
6786
|
}
|
|
6787
6787
|
const c2 = o.centre;
|
|
6788
6788
|
if (c2) {
|
|
6789
|
-
const
|
|
6790
|
-
if (
|
|
6789
|
+
const inside3 = pages2.find((p2) => c2.x >= p2.x && c2.x <= p2.x + p2.width && c2.y >= p2.y && c2.y <= p2.y + p2.height);
|
|
6790
|
+
if (inside3) return inside3;
|
|
6791
6791
|
let best = pages2[0], bestD = Infinity;
|
|
6792
6792
|
for (const p2 of pages2) {
|
|
6793
6793
|
const dx = Math.max(p2.x - c2.x, 0, c2.x - (p2.x + p2.width));
|
|
@@ -94509,6 +94509,7 @@ function hasMessage(key5) {
|
|
|
94509
94509
|
var current2, loading, listeners, formats, asts;
|
|
94510
94510
|
var init_runtime = __esm({
|
|
94511
94511
|
"lib/i18n/runtime.ts"() {
|
|
94512
|
+
"use strict";
|
|
94512
94513
|
init_intl_messageformat();
|
|
94513
94514
|
init_icu_messageformat_parser();
|
|
94514
94515
|
init_catalogs();
|
|
@@ -97385,7 +97386,6 @@ function selectionWorldBounds(nodes, ids2, scrollState) {
|
|
|
97385
97386
|
}
|
|
97386
97387
|
var init_selection_bounds = __esm({
|
|
97387
97388
|
"lib/editor/selection-bounds.ts"() {
|
|
97388
|
-
"use strict";
|
|
97389
97389
|
init_scene_graph();
|
|
97390
97390
|
init_transform();
|
|
97391
97391
|
}
|
|
@@ -97577,7 +97577,6 @@ function relinkCopies(doc2, copies) {
|
|
|
97577
97577
|
var TEXT_PATH_SOURCE_TYPES, isPathSource;
|
|
97578
97578
|
var init_text_links = __esm({
|
|
97579
97579
|
"lib/document/text-links.ts"() {
|
|
97580
|
-
"use strict";
|
|
97581
97580
|
init_transform();
|
|
97582
97581
|
TEXT_PATH_SOURCE_TYPES = ["VECTOR", "ELLIPSE", "RECTANGLE", "POLYGON", "STAR", "LINE", "ARROW", "FRAME"];
|
|
97583
97582
|
isPathSource = (n) => !!n && TEXT_PATH_SOURCE_TYPES.includes(n.type);
|
|
@@ -248026,7 +248025,6 @@ function repairCompositions(comps, nodes) {
|
|
|
248026
248025
|
var isObj5, finite6, optFinite, isVec2, TIMELINE_COLOR_IDS, TIMELINE_COLORS, UNITS, ORDERS, PROP_KEYS, ANIMATOR_ID, MOTION_TYPES, TRANSITIONS, isFraction, MEDIA_HASH;
|
|
248027
248026
|
var init_invariants = __esm({
|
|
248028
248027
|
"lib/motion/invariants.ts"() {
|
|
248029
|
-
"use strict";
|
|
248030
248028
|
init_easing();
|
|
248031
248029
|
init_properties();
|
|
248032
248030
|
init_markers();
|
|
@@ -249149,7 +249147,6 @@ function beforeWrite() {
|
|
|
249149
249147
|
var leave;
|
|
249150
249148
|
var init_read_only = __esm({
|
|
249151
249149
|
"lib/editor/modes/read-only.ts"() {
|
|
249152
|
-
"use strict";
|
|
249153
249150
|
leave = null;
|
|
249154
249151
|
}
|
|
249155
249152
|
});
|
|
@@ -251994,12 +251991,65 @@ var require_polygon_clipping_cjs = __commonJS({
|
|
|
251994
251991
|
}
|
|
251995
251992
|
});
|
|
251996
251993
|
|
|
251994
|
+
// lib/engine/geometry/winding.ts
|
|
251995
|
+
function interiorPoint(r) {
|
|
251996
|
+
let cx = 0, cy = 0;
|
|
251997
|
+
for (const [x2, y] of r) {
|
|
251998
|
+
cx += x2;
|
|
251999
|
+
cy += y;
|
|
252000
|
+
}
|
|
252001
|
+
const centroid2 = [cx / r.length, cy / r.length];
|
|
252002
|
+
if (inside(centroid2, r)) return centroid2;
|
|
252003
|
+
const [a, b, c2] = [r[0], r[1], r[2] ?? r[0]];
|
|
252004
|
+
return [(a[0] + b[0] + c2[0]) / 3, (a[1] + b[1] + c2[1]) / 3];
|
|
252005
|
+
}
|
|
252006
|
+
function nonzeroMultiPoly(rings) {
|
|
252007
|
+
const usable = rings.filter((r) => r.length >= 3);
|
|
252008
|
+
if (!usable.length) return [];
|
|
252009
|
+
const polys = usable.map((r) => [r]);
|
|
252010
|
+
if (usable.length === 1) return import_polygon_clipping.default.union(polys[0]);
|
|
252011
|
+
const areas = usable.map(signedArea);
|
|
252012
|
+
const add3 = [], sub2 = [];
|
|
252013
|
+
usable.forEach((r, i2) => {
|
|
252014
|
+
const p2 = interiorPoint(r);
|
|
252015
|
+
let w = Math.sign(areas[i2]);
|
|
252016
|
+
usable.forEach((o, j) => {
|
|
252017
|
+
if (j !== i2 && Math.abs(areas[j]) > Math.abs(areas[i2]) && inside(p2, o)) w += Math.sign(areas[j]);
|
|
252018
|
+
});
|
|
252019
|
+
(w === 0 ? sub2 : add3).push(polys[i2]);
|
|
252020
|
+
});
|
|
252021
|
+
if (!add3.length) return [];
|
|
252022
|
+
const filled2 = import_polygon_clipping.default.union(add3[0], ...add3.slice(1));
|
|
252023
|
+
return sub2.length ? import_polygon_clipping.default.difference(filled2, ...sub2) : filled2;
|
|
252024
|
+
}
|
|
252025
|
+
var import_polygon_clipping, signedArea, inside;
|
|
252026
|
+
var init_winding = __esm({
|
|
252027
|
+
"lib/engine/geometry/winding.ts"() {
|
|
252028
|
+
"use strict";
|
|
252029
|
+
import_polygon_clipping = __toESM(require_polygon_clipping_cjs());
|
|
252030
|
+
signedArea = (r) => {
|
|
252031
|
+
let a = 0;
|
|
252032
|
+
for (let i2 = 0, j = r.length - 1; i2 < r.length; j = i2++) a += (r[j][0] - r[i2][0]) * (r[j][1] + r[i2][1]);
|
|
252033
|
+
return a / 2;
|
|
252034
|
+
};
|
|
252035
|
+
inside = ([x2, y], r) => {
|
|
252036
|
+
let c2 = false;
|
|
252037
|
+
for (let i2 = 0, j = r.length - 1; i2 < r.length; j = i2++) {
|
|
252038
|
+
const [xi, yi] = r[i2], [xj, yj] = r[j];
|
|
252039
|
+
if (yi > y !== yj > y && x2 < (xj - xi) * (y - yi) / (yj - yi) + xi) c2 = !c2;
|
|
252040
|
+
}
|
|
252041
|
+
return c2;
|
|
252042
|
+
};
|
|
252043
|
+
}
|
|
252044
|
+
});
|
|
252045
|
+
|
|
251997
252046
|
// lib/engine/geometry/triangulate.ts
|
|
251998
|
-
var
|
|
252047
|
+
var import_polygon_clipping2;
|
|
251999
252048
|
var init_triangulate = __esm({
|
|
252000
252049
|
"lib/engine/geometry/triangulate.ts"() {
|
|
252001
252050
|
"use strict";
|
|
252002
|
-
|
|
252051
|
+
import_polygon_clipping2 = __toESM(require_polygon_clipping_cjs());
|
|
252052
|
+
init_winding();
|
|
252003
252053
|
}
|
|
252004
252054
|
});
|
|
252005
252055
|
|
|
@@ -252023,7 +252073,7 @@ function computeBooleanMultiPoly(node2, allNodes) {
|
|
|
252023
252073
|
const asPolys = rings.map((r) => [r]);
|
|
252024
252074
|
let mp;
|
|
252025
252075
|
try {
|
|
252026
|
-
mp = asPolys.length > 1 ?
|
|
252076
|
+
mp = asPolys.length > 1 ? import_polygon_clipping3.default.union(asPolys[0], ...asPolys.slice(1)) : asPolys;
|
|
252027
252077
|
} catch {
|
|
252028
252078
|
mp = asPolys;
|
|
252029
252079
|
}
|
|
@@ -252035,25 +252085,25 @@ function computeBooleanMultiPoly(node2, allNodes) {
|
|
|
252035
252085
|
try {
|
|
252036
252086
|
const rest = operands.slice(1);
|
|
252037
252087
|
if (rest.length > 0) {
|
|
252038
|
-
if (op4 === "SUBTRACT") result =
|
|
252039
|
-
else if (op4 === "INTERSECT") result =
|
|
252040
|
-
else if (op4 === "EXCLUDE") result =
|
|
252041
|
-
else result =
|
|
252088
|
+
if (op4 === "SUBTRACT") result = import_polygon_clipping3.default.difference(operands[0], ...rest);
|
|
252089
|
+
else if (op4 === "INTERSECT") result = import_polygon_clipping3.default.intersection(operands[0], ...rest);
|
|
252090
|
+
else if (op4 === "EXCLUDE") result = import_polygon_clipping3.default.xor(operands[0], ...rest);
|
|
252091
|
+
else result = import_polygon_clipping3.default.union(operands[0], ...rest);
|
|
252042
252092
|
}
|
|
252043
252093
|
} catch {
|
|
252044
252094
|
try {
|
|
252045
|
-
result =
|
|
252095
|
+
result = import_polygon_clipping3.default.union(operands[0], ...operands.slice(1));
|
|
252046
252096
|
} catch {
|
|
252047
252097
|
result = operands[0];
|
|
252048
252098
|
}
|
|
252049
252099
|
}
|
|
252050
252100
|
return result;
|
|
252051
252101
|
}
|
|
252052
|
-
var
|
|
252102
|
+
var import_polygon_clipping3;
|
|
252053
252103
|
var init_vector_geometry_cache = __esm({
|
|
252054
252104
|
"lib/engine/vector-geometry-cache.ts"() {
|
|
252055
252105
|
"use strict";
|
|
252056
|
-
|
|
252106
|
+
import_polygon_clipping3 = __toESM(require_polygon_clipping_cjs());
|
|
252057
252107
|
init_flatten();
|
|
252058
252108
|
init_triangulate();
|
|
252059
252109
|
init_shape_outline();
|
|
@@ -252072,11 +252122,11 @@ function arrangementFaces(shapes) {
|
|
|
252072
252122
|
const next2 = [];
|
|
252073
252123
|
let rest = shape2;
|
|
252074
252124
|
for (const f2 of faces2) {
|
|
252075
|
-
const
|
|
252076
|
-
if (solid(
|
|
252077
|
-
const outside = op2(
|
|
252125
|
+
const inside3 = op2(import_polygon_clipping4.default.intersection, f2.mp, shape2);
|
|
252126
|
+
if (solid(inside3)) next2.push({ mp: inside3, sources: [...f2.sources, i2] });
|
|
252127
|
+
const outside = op2(import_polygon_clipping4.default.difference, f2.mp, shape2);
|
|
252078
252128
|
if (solid(outside)) next2.push({ mp: outside, sources: f2.sources });
|
|
252079
|
-
if (solid(
|
|
252129
|
+
if (solid(inside3)) rest = op2(import_polygon_clipping4.default.difference, rest, f2.mp);
|
|
252080
252130
|
}
|
|
252081
252131
|
if (solid(rest)) next2.push({ mp: rest, sources: [i2] });
|
|
252082
252132
|
faces2 = next2;
|
|
@@ -252085,15 +252135,15 @@ function arrangementFaces(shapes) {
|
|
|
252085
252135
|
}
|
|
252086
252136
|
function pointInMultiPoly(mp, x2, y) {
|
|
252087
252137
|
for (const poly of mp) {
|
|
252088
|
-
let
|
|
252138
|
+
let inside3 = false;
|
|
252089
252139
|
for (const ring of poly) {
|
|
252090
252140
|
for (let i2 = 0, j = ring.length - 1; i2 < ring.length; j = i2++) {
|
|
252091
252141
|
const [xi, yi] = ring[i2];
|
|
252092
252142
|
const [xj, yj] = ring[j];
|
|
252093
|
-
if (yi > y !== yj > y && x2 < (xj - xi) * (y - yi) / (yj - yi) + xi)
|
|
252143
|
+
if (yi > y !== yj > y && x2 < (xj - xi) * (y - yi) / (yj - yi) + xi) inside3 = !inside3;
|
|
252094
252144
|
}
|
|
252095
252145
|
}
|
|
252096
|
-
if (
|
|
252146
|
+
if (inside3) return true;
|
|
252097
252147
|
}
|
|
252098
252148
|
return false;
|
|
252099
252149
|
}
|
|
@@ -252105,16 +252155,16 @@ function unionFaces(faces2, picked) {
|
|
|
252105
252155
|
const parts = picked.map((i2) => faces2[i2]?.mp).filter(solid);
|
|
252106
252156
|
if (parts.length === 0) return [];
|
|
252107
252157
|
try {
|
|
252108
|
-
return parts.length > 1 ?
|
|
252158
|
+
return parts.length > 1 ? import_polygon_clipping4.default.union(parts[0], ...parts.slice(1)) : parts[0];
|
|
252109
252159
|
} catch {
|
|
252110
252160
|
return parts[0];
|
|
252111
252161
|
}
|
|
252112
252162
|
}
|
|
252113
|
-
var
|
|
252163
|
+
var import_polygon_clipping4, MAX_SHAPE_BUILDER_SHAPES, area2, MIN_FACE_AREA, solid, op2;
|
|
252114
252164
|
var init_regions = __esm({
|
|
252115
252165
|
"lib/engine/geometry/regions.ts"() {
|
|
252116
252166
|
"use strict";
|
|
252117
|
-
|
|
252167
|
+
import_polygon_clipping4 = __toESM(require_polygon_clipping_cjs());
|
|
252118
252168
|
MAX_SHAPE_BUILDER_SHAPES = 12;
|
|
252119
252169
|
area2 = (mp) => {
|
|
252120
252170
|
let a = 0;
|
|
@@ -252216,7 +252266,7 @@ function bufferPolylines(lines2, width) {
|
|
|
252216
252266
|
}
|
|
252217
252267
|
if (pieces.length === 0) return [];
|
|
252218
252268
|
try {
|
|
252219
|
-
return pieces.length > 1 ?
|
|
252269
|
+
return pieces.length > 1 ? import_polygon_clipping5.default.union(pieces[0], ...pieces.slice(1)) : [pieces[0]];
|
|
252220
252270
|
} catch {
|
|
252221
252271
|
return pieces.map((p2) => [p2[0]]);
|
|
252222
252272
|
}
|
|
@@ -252225,7 +252275,7 @@ function combineRings(rings, mode2) {
|
|
|
252225
252275
|
const polys = rings.filter((r) => r.length >= 3).map((r) => [r]);
|
|
252226
252276
|
if (polys.length === 0) return [];
|
|
252227
252277
|
try {
|
|
252228
|
-
return polys.length > 1 ?
|
|
252278
|
+
return polys.length > 1 ? import_polygon_clipping5.default[mode2](polys[0], ...polys.slice(1)) : [polys[0]];
|
|
252229
252279
|
} catch {
|
|
252230
252280
|
return polys.map((p2) => [p2[0]]);
|
|
252231
252281
|
}
|
|
@@ -252239,8 +252289,15 @@ function nodeWorldMultiPoly(doc2, id3) {
|
|
|
252239
252289
|
return mp.map((poly) => poly.map((ring) => ring.map(([x2, y]) => place4(x2, y))));
|
|
252240
252290
|
}
|
|
252241
252291
|
const rings = nodeWorldRings(doc2, id3);
|
|
252242
|
-
|
|
252243
|
-
|
|
252292
|
+
if (node2.type === "VECTOR") {
|
|
252293
|
+
if (node2.fillRule === "EVENODD") return combineRings(rings, "xor");
|
|
252294
|
+
try {
|
|
252295
|
+
return nonzeroMultiPoly(rings);
|
|
252296
|
+
} catch {
|
|
252297
|
+
return combineRings(rings, "union");
|
|
252298
|
+
}
|
|
252299
|
+
}
|
|
252300
|
+
return combineRings(rings, "union");
|
|
252244
252301
|
}
|
|
252245
252302
|
function nodeAreaMultiPoly(doc2, id3) {
|
|
252246
252303
|
if (!doc2.nodes[id3]) return [];
|
|
@@ -252250,13 +252307,23 @@ function nodeAreaMultiPoly(doc2, id3) {
|
|
|
252250
252307
|
}
|
|
252251
252308
|
function flattenNodesMultiPoly(doc2, ids2) {
|
|
252252
252309
|
const operands = [];
|
|
252253
|
-
|
|
252254
|
-
const
|
|
252255
|
-
if (
|
|
252256
|
-
|
|
252310
|
+
const visit2 = (id3) => {
|
|
252311
|
+
const n = doc2.nodes[id3];
|
|
252312
|
+
if (!n || n.visible === false) return;
|
|
252313
|
+
if (n.type !== "GROUP") {
|
|
252314
|
+
const mp = n.type === "FRAME" || n.type === "COMPONENT" || n.type === "INSTANCE" || n.type === "SECTION" ? (n.fills ?? []).some((f2) => f2.visible !== false) ? nodeWorldMultiPoly(doc2, id3) : [] : nodeAreaMultiPoly(doc2, id3);
|
|
252315
|
+
if (mp.length > 0) operands.push(mp);
|
|
252316
|
+
}
|
|
252317
|
+
if (n.type !== "BOOLEAN") for (const c2 of n.childIds ?? []) visit2(c2);
|
|
252318
|
+
};
|
|
252319
|
+
ids2.forEach(visit2);
|
|
252320
|
+
return unionAll(operands);
|
|
252321
|
+
}
|
|
252322
|
+
function unionAll(mps) {
|
|
252323
|
+
const operands = mps.filter((mp) => mp.length > 0);
|
|
252257
252324
|
if (operands.length === 0) return [];
|
|
252258
252325
|
try {
|
|
252259
|
-
return operands.length > 1 ?
|
|
252326
|
+
return operands.length > 1 ? import_polygon_clipping5.default.union(operands[0], ...operands.slice(1)) : operands[0];
|
|
252260
252327
|
} catch {
|
|
252261
252328
|
return operands[0];
|
|
252262
252329
|
}
|
|
@@ -252282,7 +252349,7 @@ function outlineStrokeMultiPoly(doc2, id3) {
|
|
|
252282
252349
|
const buffer2 = bufferPolylines(lines2, width * 2);
|
|
252283
252350
|
if (fill.length === 0 || buffer2.length === 0) return bufferPolylines(lines2, width);
|
|
252284
252351
|
try {
|
|
252285
|
-
return alignment === "INSIDE" ?
|
|
252352
|
+
return alignment === "INSIDE" ? import_polygon_clipping5.default.intersection(buffer2, fill) : import_polygon_clipping5.default.difference(buffer2, fill);
|
|
252286
252353
|
} catch {
|
|
252287
252354
|
return bufferPolylines(lines2, width);
|
|
252288
252355
|
}
|
|
@@ -252314,16 +252381,17 @@ function shapeBuilderFaces(doc2, ids2) {
|
|
|
252314
252381
|
facesCache = { nodes: doc2.nodes, key: key5, faces: faces2 };
|
|
252315
252382
|
return faces2;
|
|
252316
252383
|
}
|
|
252317
|
-
var
|
|
252384
|
+
var import_polygon_clipping5, JOIN_CIRCLE_SEGMENTS, facesCache;
|
|
252318
252385
|
var init_vector_ops = __esm({
|
|
252319
252386
|
"lib/engine/geometry/vector-ops.ts"() {
|
|
252320
252387
|
"use strict";
|
|
252321
|
-
|
|
252388
|
+
import_polygon_clipping5 = __toESM(require_polygon_clipping_cjs());
|
|
252322
252389
|
init_scene_graph();
|
|
252323
252390
|
init_transform();
|
|
252324
252391
|
init_shape_outline();
|
|
252325
252392
|
init_flatten();
|
|
252326
252393
|
init_vector_geometry_cache();
|
|
252394
|
+
init_winding();
|
|
252327
252395
|
init_regions();
|
|
252328
252396
|
JOIN_CIRCLE_SEGMENTS = 16;
|
|
252329
252397
|
facesCache = null;
|
|
@@ -252377,15 +252445,15 @@ var init_brush_along_path = __esm({
|
|
|
252377
252445
|
|
|
252378
252446
|
// lib/engine/geometry/polygon.ts
|
|
252379
252447
|
function pointInPolygon(p2, poly) {
|
|
252380
|
-
let
|
|
252448
|
+
let inside3 = false;
|
|
252381
252449
|
for (let i2 = 0, j = poly.length - 1; i2 < poly.length; j = i2++) {
|
|
252382
252450
|
const a = poly[i2], b = poly[j];
|
|
252383
252451
|
if (a.y > p2.y !== b.y > p2.y) {
|
|
252384
252452
|
const xCross = a.x + (p2.y - a.y) * (b.x - a.x) / (b.y - a.y);
|
|
252385
|
-
if (p2.x < xCross)
|
|
252453
|
+
if (p2.x < xCross) inside3 = !inside3;
|
|
252386
252454
|
}
|
|
252387
252455
|
}
|
|
252388
|
-
return
|
|
252456
|
+
return inside3;
|
|
252389
252457
|
}
|
|
252390
252458
|
var init_polygon = __esm({
|
|
252391
252459
|
"lib/engine/geometry/polygon.ts"() {
|
|
@@ -252425,8 +252493,8 @@ function enclosedRegion(shapes, pt, view2) {
|
|
|
252425
252493
|
}
|
|
252426
252494
|
try {
|
|
252427
252495
|
let region = rectMP(view2);
|
|
252428
|
-
for (const c2 of containing) region =
|
|
252429
|
-
if (subtract.length) region =
|
|
252496
|
+
for (const c2 of containing) region = import_polygon_clipping6.default.intersection(region, c2);
|
|
252497
|
+
if (subtract.length) region = import_polygon_clipping6.default.difference(region, ...subtract);
|
|
252430
252498
|
const hit = region.find((p2) => pointInPoly(pt, p2));
|
|
252431
252499
|
if (!hit) return { ok: false, reason: "EMPTY" };
|
|
252432
252500
|
if (!containing.length && touchesRect(hit, view2)) return { ok: false, reason: "OPEN" };
|
|
@@ -252477,11 +252545,11 @@ function findEnclosedRegion(doc2, pageId2, pt, view2) {
|
|
|
252477
252545
|
walk4(pageId2);
|
|
252478
252546
|
return enclosedRegion(shapes, pt, view2);
|
|
252479
252547
|
}
|
|
252480
|
-
var
|
|
252548
|
+
var import_polygon_clipping6, ringPts, pointInMP, rectMP;
|
|
252481
252549
|
var init_bucket = __esm({
|
|
252482
252550
|
"lib/engine/geometry/bucket.ts"() {
|
|
252483
252551
|
"use strict";
|
|
252484
|
-
|
|
252552
|
+
import_polygon_clipping6 = __toESM(require_polygon_clipping_cjs());
|
|
252485
252553
|
init_scene_graph();
|
|
252486
252554
|
init_vector_ops();
|
|
252487
252555
|
init_polygon();
|
|
@@ -252591,7 +252659,6 @@ function resizeWindow(doc2, target2, rect) {
|
|
|
252591
252659
|
}
|
|
252592
252660
|
var init_crop = __esm({
|
|
252593
252661
|
"lib/editor/crop.ts"() {
|
|
252594
|
-
"use strict";
|
|
252595
252662
|
init_dist_node();
|
|
252596
252663
|
init_scene_graph();
|
|
252597
252664
|
init_photo_frames();
|
|
@@ -256124,7 +256191,6 @@ fn shade(uv: vec2<f32>, res: vec2<f32>, tm: f32) -> vec4<f32> {
|
|
|
256124
256191
|
var SHADER_PRESETS, shaderPreset, legacyPresetOf, DEFAULT_SHADER_PRESET, DEFAULT_TEXTURE_PARAMS, f, vec4, NOISE_LIB;
|
|
256125
256192
|
var init_shader_presets = __esm({
|
|
256126
256193
|
"lib/engine/shader-presets.ts"() {
|
|
256127
|
-
"use strict";
|
|
256128
256194
|
init_shader_graph();
|
|
256129
256195
|
init_shader_graph_presets();
|
|
256130
256196
|
init_shader_presets_legacy();
|
|
@@ -257088,7 +257154,6 @@ function followPeers(peers) {
|
|
|
257088
257154
|
var PALETTE, usePresence, awareness, CURSOR_SEND_MS, VIEWPORT_SEND_MS, cursorTimer, pendingCursor, sentCursor, EMOTE_MS, lastFollowCamera;
|
|
257089
257155
|
var init_presence = __esm({
|
|
257090
257156
|
"lib/collab/presence.ts"() {
|
|
257091
|
-
"use strict";
|
|
257092
257157
|
init_esm();
|
|
257093
257158
|
init_editor_store();
|
|
257094
257159
|
init_status_announcements();
|
|
@@ -257645,10 +257710,10 @@ function collapse(doc2) {
|
|
|
257645
257710
|
else groups.set(h, [id3]);
|
|
257646
257711
|
}
|
|
257647
257712
|
const chosen = [];
|
|
257648
|
-
const
|
|
257713
|
+
const inside3 = /* @__PURE__ */ new Set();
|
|
257649
257714
|
const sorted = [...groups.values()].filter((g) => g.length >= MIN_COPIES).sort((a, b) => (size6.get(b[0]) ?? 0) - (size6.get(a[0]) ?? 0));
|
|
257650
257715
|
const within3 = (id3) => {
|
|
257651
|
-
for (let p2 = nodes[id3]?.parentId, guard2 = 0; p2 && guard2 < 200; p2 = nodes[p2]?.parentId, guard2++) if (
|
|
257716
|
+
for (let p2 = nodes[id3]?.parentId, guard2 = 0; p2 && guard2 < 200; p2 = nodes[p2]?.parentId, guard2++) if (inside3.has(p2)) return true;
|
|
257652
257717
|
return false;
|
|
257653
257718
|
};
|
|
257654
257719
|
for (const g of sorted) {
|
|
@@ -257656,7 +257721,7 @@ function collapse(doc2) {
|
|
|
257656
257721
|
const copies = g.filter((id3) => !within3(id3) && (id3 === rep || sameContents(nodes, rep, id3)));
|
|
257657
257722
|
if (copies.length < MIN_COPIES || !copies.includes(rep)) continue;
|
|
257658
257723
|
chosen.push(copies);
|
|
257659
|
-
for (const id3 of copies)
|
|
257724
|
+
for (const id3 of copies) inside3.add(id3);
|
|
257660
257725
|
}
|
|
257661
257726
|
if (!chosen.length) return doc2;
|
|
257662
257727
|
const out = { ...nodes };
|
|
@@ -258001,7 +258066,6 @@ function onTabMessage(fn) {
|
|
|
258001
258066
|
var EDITOR_HOME, localDocPath, cloudFilePath, CHANNEL2, channel2;
|
|
258002
258067
|
var init_tab_mode = __esm({
|
|
258003
258068
|
"lib/desktop/tab-mode.ts"() {
|
|
258004
|
-
"use strict";
|
|
258005
258069
|
EDITOR_HOME = "/home";
|
|
258006
258070
|
localDocPath = (docId) => `${EDITOR_HOME}?doc=${encodeURIComponent(docId)}`;
|
|
258007
258071
|
cloudFilePath = (key5) => `/pop/${encodeURIComponent(key5)}`;
|
|
@@ -258018,6 +258082,64 @@ function scaleVectorPaths(paths, sx, sy, rebuild) {
|
|
|
258018
258082
|
return { ...path, points, data: rebuild(points, path.closed) };
|
|
258019
258083
|
});
|
|
258020
258084
|
}
|
|
258085
|
+
function scaledChildProps(orig, sx, sy, rebuild) {
|
|
258086
|
+
return {
|
|
258087
|
+
x: orig.x * sx,
|
|
258088
|
+
y: orig.y * sy,
|
|
258089
|
+
width: orig.width * sx,
|
|
258090
|
+
height: orig.height * sy,
|
|
258091
|
+
...orig.type === "VECTOR" ? { paths: scaleVectorPaths(orig.paths, sx, sy, rebuild) } : {}
|
|
258092
|
+
};
|
|
258093
|
+
}
|
|
258094
|
+
function rebuildVectorData(points, closed) {
|
|
258095
|
+
if (points.length < 2) return [];
|
|
258096
|
+
const data = [];
|
|
258097
|
+
data.push("M", points[0].x, points[0].y);
|
|
258098
|
+
for (let i2 = 1; i2 < points.length; i2++) {
|
|
258099
|
+
const prev = points[i2 - 1];
|
|
258100
|
+
const curr = points[i2];
|
|
258101
|
+
if (prev.handleOut && curr.handleIn) {
|
|
258102
|
+
data.push("C", prev.handleOut.x, prev.handleOut.y, curr.handleIn.x, curr.handleIn.y, curr.x, curr.y);
|
|
258103
|
+
} else if (prev.handleOut) {
|
|
258104
|
+
data.push("Q", prev.handleOut.x, prev.handleOut.y, curr.x, curr.y);
|
|
258105
|
+
} else if (curr.handleIn) {
|
|
258106
|
+
data.push("Q", curr.handleIn.x, curr.handleIn.y, curr.x, curr.y);
|
|
258107
|
+
} else {
|
|
258108
|
+
data.push("L", curr.x, curr.y);
|
|
258109
|
+
}
|
|
258110
|
+
}
|
|
258111
|
+
if (closed) {
|
|
258112
|
+
const prev = points[points.length - 1];
|
|
258113
|
+
const curr = points[0];
|
|
258114
|
+
if (prev.handleOut && curr.handleIn) {
|
|
258115
|
+
data.push("C", prev.handleOut.x, prev.handleOut.y, curr.handleIn.x, curr.handleIn.y, curr.x, curr.y);
|
|
258116
|
+
} else if (prev.handleOut) {
|
|
258117
|
+
data.push("Q", prev.handleOut.x, prev.handleOut.y, curr.x, curr.y);
|
|
258118
|
+
} else if (curr.handleIn) {
|
|
258119
|
+
data.push("Q", curr.handleIn.x, curr.handleIn.y, curr.x, curr.y);
|
|
258120
|
+
}
|
|
258121
|
+
data.push("Z");
|
|
258122
|
+
}
|
|
258123
|
+
return data;
|
|
258124
|
+
}
|
|
258125
|
+
function scaleSubtreePatches(nodes, id3, sx, sy, includeSelf = true) {
|
|
258126
|
+
const out = /* @__PURE__ */ new Map();
|
|
258127
|
+
const root2 = nodes[id3];
|
|
258128
|
+
if (!root2 || sx === 1 && sy === 1) return out;
|
|
258129
|
+
if (includeSelf && root2.type === "VECTOR") out.set(id3, { paths: scaleVectorPaths(root2.paths, sx, sy, rebuildVectorData) });
|
|
258130
|
+
const walk4 = (parent) => {
|
|
258131
|
+
for (const cid of parent.childIds ?? []) {
|
|
258132
|
+
const c2 = nodes[cid];
|
|
258133
|
+
if (!c2) continue;
|
|
258134
|
+
const patch2 = { ...scaledChildProps(c2, sx, sy, rebuildVectorData) };
|
|
258135
|
+
if (c2.type === "TEXT") patch2.fontSize = (c2.fontSize ?? 16) * Math.min(sx, sy);
|
|
258136
|
+
out.set(cid, patch2);
|
|
258137
|
+
walk4(c2);
|
|
258138
|
+
}
|
|
258139
|
+
};
|
|
258140
|
+
if (root2.type === "GROUP" || root2.type === "BOOLEAN" || !includeSelf) walk4(root2);
|
|
258141
|
+
return out;
|
|
258142
|
+
}
|
|
258021
258143
|
var scalePoint;
|
|
258022
258144
|
var init_scale_geometry = __esm({
|
|
258023
258145
|
"lib/document/scale-geometry.ts"() {
|
|
@@ -260624,7 +260746,6 @@ function retuneShaderAudio(node2, fillId) {
|
|
|
260624
260746
|
}
|
|
260625
260747
|
var init_shader_audio = __esm({
|
|
260626
260748
|
"lib/motion/shader-audio.ts"() {
|
|
260627
|
-
"use strict";
|
|
260628
260749
|
init_shader_params();
|
|
260629
260750
|
init_modifier_edit();
|
|
260630
260751
|
init_keys();
|
|
@@ -262658,7 +262779,6 @@ function formatLimit(key5, max3) {
|
|
|
262658
262779
|
var formatBytes;
|
|
262659
262780
|
var init_limits2 = __esm({
|
|
262660
262781
|
"lib/billing/limits.ts"() {
|
|
262661
|
-
"use strict";
|
|
262662
262782
|
init_format();
|
|
262663
262783
|
init_plans();
|
|
262664
262784
|
formatBytes = formatFileSize;
|
|
@@ -306875,7 +306995,6 @@ function decodeSource(key5, label3) {
|
|
|
306875
306995
|
var DECODE_CACHE_BYTES, cache7, pending4, held, sizeOf, lengths, decodedLengths, DECODE_TIMEOUT_MS, decodedAudio, decodedSource, pcmOf;
|
|
306876
306996
|
var init_audio_decode = __esm({
|
|
306877
306997
|
"lib/motion/audio-decode.ts"() {
|
|
306878
|
-
"use strict";
|
|
306879
306998
|
init_media_store();
|
|
306880
306999
|
init_audio_plan();
|
|
306881
307000
|
init_time_stretch();
|
|
@@ -311656,6 +311775,7 @@ function startCloudSync() {
|
|
|
311656
311775
|
var status, readOnlyDoc, activeLink, statusListeners, notice, urlArmed, opening, syncStatus, canEdit, uploaded, MEDIA_UPLOAD_PARALLEL, pushTimer, pushing, dirty, pendingMedia, collab, collabSession, collabAnonymous, uploadedThumbs, thumbCheckedAt, THUMB_EVERY_MS, THUMB_MIN_GAP_MS, putThumbnail, openingFiles, mediaHealed, started2;
|
|
311657
311776
|
var init_sync2 = __esm({
|
|
311658
311777
|
"lib/client/cloud/sync.ts"() {
|
|
311778
|
+
"use strict";
|
|
311659
311779
|
init_paint_repair();
|
|
311660
311780
|
init_migrate();
|
|
311661
311781
|
init_view();
|
|
@@ -312926,7 +313046,6 @@ function applyTextPath(layout2, path, tp, rebase = true) {
|
|
|
312926
313046
|
var defaultCircleRadius, ownsPath, mapPoint;
|
|
312927
313047
|
var init_text_path = __esm({
|
|
312928
313048
|
"lib/engine/text/text-path.ts"() {
|
|
312929
|
-
"use strict";
|
|
312930
313049
|
init_scene_graph();
|
|
312931
313050
|
init_transform();
|
|
312932
313051
|
init_shape_to_path();
|
|
@@ -313044,7 +313163,6 @@ function areaBounds(rings) {
|
|
|
313044
313163
|
}
|
|
313045
313164
|
var init_text_area = __esm({
|
|
313046
313165
|
"lib/engine/text/text-area.ts"() {
|
|
313047
|
-
"use strict";
|
|
313048
313166
|
}
|
|
313049
313167
|
});
|
|
313050
313168
|
|
|
@@ -315582,12 +315700,12 @@ function textStrokeSVG(node2) {
|
|
|
315582
315700
|
const w = Array.isArray(stroke3.width) ? Math.max(...stroke3.width) : stroke3.width;
|
|
315583
315701
|
if (!(w > 0)) return null;
|
|
315584
315702
|
const behind = strokeBehindFill(node2) || stroke3.alignment === "OUTSIDE";
|
|
315585
|
-
const
|
|
315586
|
-
if (
|
|
315703
|
+
const inside3 = stroke3.alignment === "INSIDE";
|
|
315704
|
+
if (inside3 && behind) return null;
|
|
315587
315705
|
const alpha2 = (stroke3.color.a ?? 1) * (stroke3.opacity ?? 1);
|
|
315588
315706
|
const join13 = stroke3.join === "ROUND" ? "round" : stroke3.join === "BEVEL" ? "bevel" : "miter";
|
|
315589
315707
|
const attrs = `stroke="${colorToSVG(stroke3.color)}"${alpha2 < 1 ? ` stroke-opacity="${fmt2(alpha2)}"` : ""} stroke-width="${fmt2(stroke3.alignment === "CENTER" ? w : w * 2)}" stroke-linejoin="${join13}"${behind ? ' paint-order="stroke fill"' : ""}`;
|
|
315590
|
-
return { attrs, behind, inside:
|
|
315708
|
+
return { attrs, behind, inside: inside3 };
|
|
315591
315709
|
}
|
|
315592
315710
|
function textFillAttr(resolved, node2, ctx2) {
|
|
315593
315711
|
const fill0 = resolved.fills?.[0];
|
|
@@ -316511,12 +316629,12 @@ Q
|
|
|
316511
316629
|
};
|
|
316512
316630
|
const paintStrokes = () => {
|
|
316513
316631
|
for (const s of item.strokes) {
|
|
316514
|
-
const
|
|
316515
|
-
const wdt =
|
|
316632
|
+
const inside3 = s.alignment === "INSIDE";
|
|
316633
|
+
const wdt = inside3 ? s.width * 2 : s.width;
|
|
316516
316634
|
this.w(`q /${this.gs(1, opacity * s.alpha, blend2)} gs ${this.res.color.stroke(s.color)} ${num7(wdt)} w ${CAP2[s.cap]} J ${JOIN2[s.join]} j`);
|
|
316517
316635
|
this.w(s.dash ? ` [${num7(s.dash[0])} ${num7(s.dash[1])}] 0 d
|
|
316518
316636
|
` : " [] 0 d\n");
|
|
316519
|
-
if (
|
|
316637
|
+
if (inside3) this.w(`${ops2}${clipOp} n
|
|
316520
316638
|
`);
|
|
316521
316639
|
this.w(`${ops2}S
|
|
316522
316640
|
Q
|
|
@@ -316689,8 +316807,8 @@ function removeOverlaps(cmds) {
|
|
|
316689
316807
|
break;
|
|
316690
316808
|
}
|
|
316691
316809
|
if (!touching) return cmds;
|
|
316692
|
-
const pos = rings.filter((r) =>
|
|
316693
|
-
const clip =
|
|
316810
|
+
const pos = rings.filter((r) => signedArea2(r) > 0).map((r) => [r]), neg = rings.filter((r) => signedArea2(r) < 0).map((r) => [r]);
|
|
316811
|
+
const clip = import_polygon_clipping7.default;
|
|
316694
316812
|
let result;
|
|
316695
316813
|
try {
|
|
316696
316814
|
const a = pos.length ? clip.union(...pos) : [], b = neg.length ? clip.union(...neg) : [];
|
|
@@ -316803,12 +316921,12 @@ function buildCFF(name2, unitsPerEm, glyphs) {
|
|
|
316803
316921
|
}
|
|
316804
316922
|
return out;
|
|
316805
316923
|
}
|
|
316806
|
-
var
|
|
316924
|
+
var import_polygon_clipping7, signedArea2, bbox, intersects;
|
|
316807
316925
|
var init_cff = __esm({
|
|
316808
316926
|
"lib/io/pdf/cff.ts"() {
|
|
316809
316927
|
"use strict";
|
|
316810
|
-
|
|
316811
|
-
|
|
316928
|
+
import_polygon_clipping7 = __toESM(require_polygon_clipping_cjs());
|
|
316929
|
+
signedArea2 = (p2) => p2.reduce((a, [x2, y], i2) => {
|
|
316812
316930
|
const [nx, ny] = p2[(i2 + 1) % p2.length];
|
|
316813
316931
|
return a + x2 * ny - nx * y;
|
|
316814
316932
|
}, 0) / 2;
|
|
@@ -318323,6 +318441,7 @@ function agentToolList() {
|
|
|
318323
318441
|
var AGENT_CAPABILITIES, legacyCommandId, legacyTools, blobToDataUrl3, provided, legacyTool, legacyToolList;
|
|
318324
318442
|
var init_agent = __esm({
|
|
318325
318443
|
"lib/commands/agent.ts"() {
|
|
318444
|
+
"use strict";
|
|
318326
318445
|
init_types5();
|
|
318327
318446
|
init_registry();
|
|
318328
318447
|
init_errors();
|
|
@@ -318360,6 +318479,7 @@ __export(tools_exports, {
|
|
|
318360
318479
|
allTools: () => allTools,
|
|
318361
318480
|
defineTool: () => defineTool,
|
|
318362
318481
|
getTool: () => getTool,
|
|
318482
|
+
parseToolArgs: () => parseToolArgs,
|
|
318363
318483
|
registerTools: () => registerTools,
|
|
318364
318484
|
runTool: () => runTool,
|
|
318365
318485
|
toolSpecs: () => toolSpecs
|
|
@@ -318380,14 +318500,53 @@ function toolSpecs(names) {
|
|
|
318380
318500
|
function: { name: t3.name, description: t3.description, parameters: toolParameters(t3.parameters) }
|
|
318381
318501
|
}));
|
|
318382
318502
|
}
|
|
318503
|
+
function parseToolArgs(text) {
|
|
318504
|
+
try {
|
|
318505
|
+
return JSON.parse(text);
|
|
318506
|
+
} catch {
|
|
318507
|
+
}
|
|
318508
|
+
let depth = 0, inStr = false, esc3 = false;
|
|
318509
|
+
const stack = [];
|
|
318510
|
+
for (let i2 = 0; i2 < text.length; i2++) {
|
|
318511
|
+
const c2 = text[i2];
|
|
318512
|
+
if (inStr) {
|
|
318513
|
+
if (esc3) esc3 = false;
|
|
318514
|
+
else if (c2 === "\\") esc3 = true;
|
|
318515
|
+
else if (c2 === '"') inStr = false;
|
|
318516
|
+
continue;
|
|
318517
|
+
}
|
|
318518
|
+
if (c2 === '"') inStr = true;
|
|
318519
|
+
else if (c2 === "{" || c2 === "[") {
|
|
318520
|
+
stack.push(c2 === "{" ? "}" : "]");
|
|
318521
|
+
depth++;
|
|
318522
|
+
} else if (c2 === "}" || c2 === "]") {
|
|
318523
|
+
stack.pop();
|
|
318524
|
+
depth--;
|
|
318525
|
+
if (depth === 0) {
|
|
318526
|
+
try {
|
|
318527
|
+
return JSON.parse(text.slice(0, i2 + 1));
|
|
318528
|
+
} catch {
|
|
318529
|
+
return void 0;
|
|
318530
|
+
}
|
|
318531
|
+
}
|
|
318532
|
+
}
|
|
318533
|
+
}
|
|
318534
|
+
if (!stack.length) return void 0;
|
|
318535
|
+
try {
|
|
318536
|
+
return JSON.parse(text + (inStr ? '"' : "") + stack.reverse().join(""));
|
|
318537
|
+
} catch {
|
|
318538
|
+
return void 0;
|
|
318539
|
+
}
|
|
318540
|
+
}
|
|
318383
318541
|
async function runTool(name2, argsText, ctx2) {
|
|
318384
318542
|
let raw = {};
|
|
318385
318543
|
if (argsText.trim()) {
|
|
318386
|
-
|
|
318387
|
-
|
|
318388
|
-
|
|
318389
|
-
throw new ToolError(`The arguments for ${name2} were not valid JSON.`, "invalid_params");
|
|
318544
|
+
const parsed2 = parseToolArgs(argsText);
|
|
318545
|
+
if (parsed2 === void 0) {
|
|
318546
|
+
console.warn(`[agent] unparseable arguments for ${name2}:`, argsText.slice(0, 500));
|
|
318547
|
+
throw new ToolError(`The arguments for ${name2} were not valid JSON. Send one JSON object.`, "invalid_params");
|
|
318390
318548
|
}
|
|
318549
|
+
raw = parsed2;
|
|
318391
318550
|
}
|
|
318392
318551
|
return dispatch2(name2, {
|
|
318393
318552
|
surface: "agent",
|
|
@@ -319105,16 +319264,28 @@ function placeSvgLayers(doc2, parentId, svg, place4) {
|
|
|
319105
319264
|
if (n.type === "IMAGE" && !doc2.nodes[n.id] && url4?.startsWith("data:")) nodes[n.id] = { ...n, imageUrl: place4.intern(url4) };
|
|
319106
319265
|
}
|
|
319107
319266
|
}
|
|
319108
|
-
const minX = Math.min(...kids.map((
|
|
319109
|
-
const maxX = Math.max(...kids.map((
|
|
319110
|
-
for (const
|
|
319111
|
-
|
|
319112
|
-
|
|
319267
|
+
const minX = Math.min(...kids.map((k3) => k3.x)), minY = Math.min(...kids.map((k3) => k3.y));
|
|
319268
|
+
const maxX = Math.max(...kids.map((k3) => k3.x + k3.width)), maxY = Math.max(...kids.map((k3) => k3.y + k3.height));
|
|
319269
|
+
for (const k3 of kids) nodes[k3.id] = { ...nodes[k3.id], x: k3.x - minX, y: k3.y - minY };
|
|
319270
|
+
let w = Math.max(1, maxX - minX), h = Math.max(1, maxY - minY);
|
|
319271
|
+
const f2 = place4.fit;
|
|
319272
|
+
const k2 = f2 && (f2.width || f2.height) ? Math.min(f2.width ? f2.width / w : Infinity, f2.height ? f2.height / h : Infinity) : 1;
|
|
319273
|
+
if (k2 !== 1 && Number.isFinite(k2) && k2 > 0) {
|
|
319274
|
+
const wrapper = { childIds: kids.map((c2) => c2.id) };
|
|
319275
|
+
for (const [id3, patch2] of scaleSubtreePatches({ ...nodes, [frame3.id]: { ...nodes[frame3.id], ...wrapper } }, frame3.id, k2, k2, false)) {
|
|
319276
|
+
nodes[id3] = { ...nodes[id3], ...patch2 };
|
|
319277
|
+
}
|
|
319278
|
+
w *= k2;
|
|
319279
|
+
h *= k2;
|
|
319280
|
+
}
|
|
319281
|
+
const topLeft = place4.anchor === "top-left";
|
|
319282
|
+
nodes[frame3.id] = { ...nodes[frame3.id], x: Math.round(topLeft ? place4.cx : place4.cx - w / 2), y: Math.round(topLeft ? place4.cy : place4.cy - h / 2), width: w, height: h };
|
|
319113
319283
|
return { doc: { ...next2, nodes }, id: frame3.id };
|
|
319114
319284
|
}
|
|
319115
319285
|
var MAX_SVG_LAYER_BYTES;
|
|
319116
319286
|
var init_svg_place = __esm({
|
|
319117
319287
|
"lib/io/svg-place.ts"() {
|
|
319288
|
+
init_scale_geometry();
|
|
319118
319289
|
init_scene_graph();
|
|
319119
319290
|
init_svg_import();
|
|
319120
319291
|
MAX_SVG_LAYER_BYTES = 8 * 1024 * 1024;
|
|
@@ -319134,6 +319305,31 @@ function descendants(doc2, rootId, skipRoot = true) {
|
|
|
319134
319305
|
}
|
|
319135
319306
|
return out;
|
|
319136
319307
|
}
|
|
319308
|
+
function normalizeColor(c2, key5) {
|
|
319309
|
+
if (typeof c2 === "string") return parseHex(c2);
|
|
319310
|
+
const o = c2;
|
|
319311
|
+
const ch = o && ["r", "g", "b"].map((k2) => o[k2]);
|
|
319312
|
+
if (!ch || !ch.every((v) => typeof v === "number" && Number.isFinite(v))) {
|
|
319313
|
+
throw new ToolError(`${key5} has a colour without numeric r, g and b. Give 0\u20131 channels, or use set_fills with a hex colour.`);
|
|
319314
|
+
}
|
|
319315
|
+
const nums2 = ch;
|
|
319316
|
+
const scale = nums2.some((v) => v > 1) ? 255 : 1;
|
|
319317
|
+
const a = typeof o.a === "number" && Number.isFinite(o.a) ? o.a > 1 ? o.a / 255 : o.a : 1;
|
|
319318
|
+
return createColor(nums2[0] / scale, nums2[1] / scale, nums2[2] / scale, a);
|
|
319319
|
+
}
|
|
319320
|
+
function normalizePaints(v, key5) {
|
|
319321
|
+
if (!Array.isArray(v)) throw new ToolError(`${key5} must be an array of paints.`);
|
|
319322
|
+
return v.map((p2) => {
|
|
319323
|
+
const paint = p2;
|
|
319324
|
+
if (!paint || typeof paint !== "object") throw new ToolError(`${key5} must be an array of paint objects.`);
|
|
319325
|
+
const out = { ...paint };
|
|
319326
|
+
if ("color" in paint) out.color = normalizeColor(paint.color, key5);
|
|
319327
|
+
if (Array.isArray(paint.gradientStops)) {
|
|
319328
|
+
out.gradientStops = paint.gradientStops.map((s) => ({ ...s, color: normalizeColor(s.color, key5) }));
|
|
319329
|
+
}
|
|
319330
|
+
return out;
|
|
319331
|
+
});
|
|
319332
|
+
}
|
|
319137
319333
|
var nodeFind, nodeGet, nodeMeasure, docOutline, CREATABLE, nodeCreate, FORBIDDEN_PROPS, nodeUpdate, nodeDelete, nodeMove, nodeResize, nodeReparent, nodeGroup, nodeUngroup, nodeOrder, nodeAlign, nodeDistribute, nodeRename, nodeDuplicate, nodeImportSvg, nodeApplyAutoLayout, nodeSetLock, nodeSetVisibility, nodeFlip, nodeRotate;
|
|
319138
319334
|
var init_node = __esm({
|
|
319139
319335
|
"lib/commands/node.ts"() {
|
|
@@ -319146,6 +319342,7 @@ var init_node = __esm({
|
|
|
319146
319342
|
init_scene_graph();
|
|
319147
319343
|
init_types();
|
|
319148
319344
|
init_errors();
|
|
319345
|
+
init_scale_geometry();
|
|
319149
319346
|
init_plugin_shim();
|
|
319150
319347
|
init_types5();
|
|
319151
319348
|
init_ui();
|
|
@@ -319480,7 +319677,7 @@ var init_node = __esm({
|
|
|
319480
319677
|
for (const [k2, v] of Object.entries(u.props)) {
|
|
319481
319678
|
if (args2.strict && FORBIDDEN_PROPS.has(k2)) throw new ToolError(`update_nodes cannot change "${k2}". Use reparent, delete_nodes or create_node instead.`);
|
|
319482
319679
|
if (FORBIDDEN_PROPS.has(k2) || v === void 0) continue;
|
|
319483
|
-
patch2[k2] = v;
|
|
319680
|
+
patch2[k2] = k2 === "fills" || k2 === "strokes" ? normalizePaints(v, k2) : v;
|
|
319484
319681
|
changedKeys.add(k2);
|
|
319485
319682
|
}
|
|
319486
319683
|
if (args2.strict && !Object.keys(patch2).length) throw new ToolError(`No properties given for "${u.id}".`);
|
|
@@ -319595,9 +319792,21 @@ var init_node = __esm({
|
|
|
319595
319792
|
const n = doc2.nodes[id3];
|
|
319596
319793
|
const w = args2.width ?? (args2.scale ? n.width * args2.scale : n.width);
|
|
319597
319794
|
const h = args2.height ?? (args2.scale ? n.height * args2.scale : n.height);
|
|
319598
|
-
|
|
319795
|
+
const width = Math.max(AI_LIMITS.minSize, w), height = Math.max(AI_LIMITS.minSize, h);
|
|
319796
|
+
patches.set(id3, { width, height });
|
|
319797
|
+
if (n.width <= 0 || n.height <= 0) continue;
|
|
319798
|
+
for (const [pid, patch2] of scaleSubtreePatches(doc2.nodes, id3, width / n.width, height / n.height)) {
|
|
319799
|
+
patches.set(pid, { ...patches.get(pid), ...patch2 });
|
|
319800
|
+
}
|
|
319599
319801
|
}
|
|
319600
|
-
|
|
319802
|
+
let next2 = doc2;
|
|
319803
|
+
for (const id3 of ids2) {
|
|
319804
|
+
const n = doc2.nodes[id3], p2 = patches.get(id3);
|
|
319805
|
+
if (n.type === "FRAME" || n.type === "COMPONENT" || n.type === "SECTION") {
|
|
319806
|
+
next2 = applyConstraints(next2, id3, n.width, n.height, p2.width, p2.height);
|
|
319807
|
+
}
|
|
319808
|
+
}
|
|
319809
|
+
commitUpdates(ctx2, next2, patches);
|
|
319601
319810
|
return { summary: `Resized ${plural2(ids2.length, "layer")}`, data: { ids: ids2 } };
|
|
319602
319811
|
}
|
|
319603
319812
|
});
|
|
@@ -319934,6 +320143,9 @@ var init_node = __esm({
|
|
|
319934
320143
|
svg: external_exports.string().min(8).optional().describe("The full <svg>\u2026</svg> markup."),
|
|
319935
320144
|
parentId: external_exports.string().optional(),
|
|
319936
320145
|
at: external_exports.object({ x: external_exports.number(), y: external_exports.number() }).optional().describe("Place the layers in one frame centred on this point (parent coordinates) instead of at the SVG's own coordinates."),
|
|
320146
|
+
anchor: external_exports.enum(["center", "top-left"]).optional().describe("Whether `at` is the frame's centre (default) or its top-left corner."),
|
|
320147
|
+
width: external_exports.number().positive().optional().describe("With `at`: scale the artwork to fit this width (keeps proportions)."),
|
|
320148
|
+
height: external_exports.number().positive().optional().describe("With `at`: scale the artwork to fit this height (keeps proportions)."),
|
|
319937
320149
|
name: external_exports.string().max(200).optional().describe("Name of that frame (with `at`)."),
|
|
319938
320150
|
more: external_exports.array(external_exports.object({ svg: external_exports.string().min(8), name: external_exports.string().max(200).optional() })).max(50).optional().describe("Further SVGs placed in the same step (with `at`), each 24 px further down and right.")
|
|
319939
320151
|
}),
|
|
@@ -319941,7 +320153,7 @@ var init_node = __esm({
|
|
|
319941
320153
|
plugin: { method: "importSvg" },
|
|
319942
320154
|
agent: {
|
|
319943
320155
|
name: "import_svg",
|
|
319944
|
-
description:
|
|
320156
|
+
description: 'Import SVG markup as editable layers under a parent (default: the current page). Pass `at` (in the PARENT\'s coordinates) to place them in one frame centred on that point, or with its top-left there when anchor is "top-left"; add width and/or height to scale the artwork to fit that box. Returns the ids of the new top-level layers.'
|
|
319945
320157
|
},
|
|
319946
320158
|
// Paste, drop and File › Import: one undo step, and the ones that would not convert reported back so the
|
|
319947
320159
|
// caller can place them as pictures instead (lib/editor/svg-paste.ts).
|
|
@@ -319959,7 +320171,7 @@ var init_node = __esm({
|
|
|
319959
320171
|
const added2 = [];
|
|
319960
320172
|
const failed2 = [];
|
|
319961
320173
|
items.forEach((item, i2) => {
|
|
319962
|
-
const placed2 = placeSvgLayers2(next3, parentId, item.svg, { name: item.name || "SVG", cx: args2.at.x + i2 * 24, cy: args2.at.y + i2 * 24, intern: (url4) => internDataUrl2(url4) });
|
|
320174
|
+
const placed2 = placeSvgLayers2(next3, parentId, item.svg, { name: item.name || "SVG", cx: args2.at.x + i2 * 24, cy: args2.at.y + i2 * 24, anchor: args2.anchor, fit: { width: args2.width, height: args2.height }, intern: (url4) => internDataUrl2(url4) });
|
|
319963
320175
|
if (placed2) {
|
|
319964
320176
|
next3 = placed2.doc;
|
|
319965
320177
|
added2.push(placed2.id);
|
|
@@ -320954,7 +321166,8 @@ var init_paint = __esm({
|
|
|
320954
321166
|
const rec = n;
|
|
320955
321167
|
const patch2 = {};
|
|
320956
321168
|
let hit = 0;
|
|
320957
|
-
const
|
|
321169
|
+
const fillStyle = rec.fillStyleId ? doc2.styles?.[rec.fillStyleId] : void 0;
|
|
321170
|
+
const paints = fillStyle?.type === "PAINT" ? fillStyle.paints : rec.fills;
|
|
320958
321171
|
if (paints?.length) {
|
|
320959
321172
|
let changed = false;
|
|
320960
321173
|
const next2 = paints.map((p2) => {
|
|
@@ -320981,7 +321194,10 @@ var init_paint = __esm({
|
|
|
320981
321194
|
}
|
|
320982
321195
|
return out;
|
|
320983
321196
|
});
|
|
320984
|
-
if (changed)
|
|
321197
|
+
if (changed) {
|
|
321198
|
+
patch2.fills = next2;
|
|
321199
|
+
if (rec.fillStyleId) patch2.fillStyleId = void 0;
|
|
321200
|
+
}
|
|
320985
321201
|
}
|
|
320986
321202
|
const strokes = rec.strokes;
|
|
320987
321203
|
if (strokes?.length) {
|
|
@@ -320993,7 +321209,10 @@ var init_paint = __esm({
|
|
|
320993
321209
|
hit++;
|
|
320994
321210
|
return { ...s, color: c2 };
|
|
320995
321211
|
});
|
|
320996
|
-
if (changed)
|
|
321212
|
+
if (changed) {
|
|
321213
|
+
patch2.strokes = next2;
|
|
321214
|
+
if (rec.strokeStyleId) patch2.strokeStyleId = void 0;
|
|
321215
|
+
}
|
|
320997
321216
|
}
|
|
320998
321217
|
const effects = effectsOf(n);
|
|
320999
321218
|
if (effects.length) {
|
|
@@ -321024,7 +321243,7 @@ var init_paint = __esm({
|
|
|
321024
321243
|
}
|
|
321025
321244
|
}
|
|
321026
321245
|
if (!swaps) throw new ToolError(`No ${args2.from} found under ${args2.rootId ?? "the selection"}. Check the color with get_node, or raise "tolerance".`);
|
|
321027
|
-
ctx2.commit({ ...doc2, nodes });
|
|
321246
|
+
ctx2.commit(applyInvariants({ ...doc2, nodes }, touched));
|
|
321028
321247
|
return { summary: `Replaced ${args2.from} with ${args2.to} in ${plural2(touched.length, "layer")} (${swaps} paints)`, data: { ids: touched.slice(0, 50), swaps } };
|
|
321029
321248
|
}
|
|
321030
321249
|
});
|
|
@@ -328477,7 +328696,7 @@ var init_package = __esm({
|
|
|
328477
328696
|
"packages/runtime/package.json"() {
|
|
328478
328697
|
package_default = {
|
|
328479
328698
|
name: "@popcraft/runtime",
|
|
328480
|
-
version: "0.53.
|
|
328699
|
+
version: "0.53.2",
|
|
328481
328700
|
description: "What code exported from PopCraft shares: the meaning of expressions (operators and functions) and, as it grows, the parts of a design's behaviour that are common code rather than generated React.",
|
|
328482
328701
|
license: "MIT",
|
|
328483
328702
|
homepage: "https://popcraft.app/docs/exporting/nextjs",
|
|
@@ -353143,7 +353362,6 @@ function exportsOf(source3) {
|
|
|
353143
353362
|
var CODE_LIMITS, packageOf;
|
|
353144
353363
|
var init_source2 = __esm({
|
|
353145
353364
|
"lib/code/source.ts"() {
|
|
353146
|
-
"use strict";
|
|
353147
353365
|
CODE_LIMITS = { modules: 100, sourceLength: 2e5, packages: 12 };
|
|
353148
353366
|
packageOf = (spec) => spec.split("/").slice(0, spec.startsWith("@") ? 2 : 1).join("/");
|
|
353149
353367
|
}
|
|
@@ -355192,7 +355410,7 @@ function reading(doc2, ids2) {
|
|
|
355192
355410
|
}
|
|
355193
355411
|
function boardColumns(doc2, roots, looseTitle, within3) {
|
|
355194
355412
|
const areas = within3?.map((n) => boxOf(doc2, n));
|
|
355195
|
-
const wanted = (p2) => !areas || areas.some((a) =>
|
|
355413
|
+
const wanted = (p2) => !areas || areas.some((a) => inside2(p2, a));
|
|
355196
355414
|
const cards = [];
|
|
355197
355415
|
const boxes = [];
|
|
355198
355416
|
const texts = [];
|
|
@@ -355223,7 +355441,7 @@ function boardColumns(doc2, roots, looseTitle, within3) {
|
|
|
355223
355441
|
const band = b.box.minY + (b.box.maxY - b.box.minY) * 0.25;
|
|
355224
355442
|
const top = texts.filter((t3) => {
|
|
355225
355443
|
const c2 = centre(t3.box);
|
|
355226
|
-
return
|
|
355444
|
+
return inside2(c2, b.box) && c2.y <= band;
|
|
355227
355445
|
}).sort((x2, y) => x2.box.minY - y.box.minY)[0];
|
|
355228
355446
|
if (top) titles.set(b.node.id, { text: top.text, id: top.id });
|
|
355229
355447
|
else if (!DEFAULT_NAMES.test(b.node.name.trim())) titles.set(b.node.id, { text: b.node.name });
|
|
@@ -355231,7 +355449,7 @@ function boardColumns(doc2, roots, looseTitle, within3) {
|
|
|
355231
355449
|
const columnAt = (p2) => {
|
|
355232
355450
|
let best = null;
|
|
355233
355451
|
for (const b of boxes) {
|
|
355234
|
-
if (!
|
|
355452
|
+
if (!inside2(p2, b.box)) continue;
|
|
355235
355453
|
if (!best) {
|
|
355236
355454
|
best = b;
|
|
355237
355455
|
continue;
|
|
@@ -355274,7 +355492,7 @@ function boardCsv(columns) {
|
|
|
355274
355492
|
const rows = Math.max(0, ...columns.map((c2) => c2.items.length));
|
|
355275
355493
|
return toCsv([columns.map((c2) => c2.title), ...Array.from({ length: rows }, (_, i2) => columns.map((c2) => c2.items[i2] ?? ""))]);
|
|
355276
355494
|
}
|
|
355277
|
-
var MARGIN, MAX_BOARD_EXPORT_PX, textOf, boxOf, centre,
|
|
355495
|
+
var MARGIN, MAX_BOARD_EXPORT_PX, textOf, boxOf, centre, inside2, area3, textLayer, COLUMN_TYPES;
|
|
355278
355496
|
var init_board_export = __esm({
|
|
355279
355497
|
"lib/popcorn/board-export.ts"() {
|
|
355280
355498
|
init_scene_graph();
|
|
@@ -355284,7 +355502,7 @@ var init_board_export = __esm({
|
|
|
355284
355502
|
textOf = (n) => (n.text ?? "").replace(/\s+/g, " ").trim();
|
|
355285
355503
|
boxOf = (doc2, n) => uprightBounds(getWorldTransform(doc2, n.id), n.width, n.height);
|
|
355286
355504
|
centre = (b) => ({ x: (b.minX + b.maxX) / 2, y: (b.minY + b.maxY) / 2 });
|
|
355287
|
-
|
|
355505
|
+
inside2 = (p2, b) => p2.x >= b.minX && p2.x <= b.maxX && p2.y >= b.minY && p2.y <= b.maxY;
|
|
355288
355506
|
area3 = (b) => (b.maxX - b.minX) * (b.maxY - b.minY);
|
|
355289
355507
|
textLayer = (n) => n.type === "TEXT" ? (n.characters ?? "").replace(/\s+/g, " ").trim() : "";
|
|
355290
355508
|
COLUMN_TYPES = /* @__PURE__ */ new Set(["FRAME", "SECTION", "GROUP", "RECTANGLE", "INSTANCE", "COMPONENT", "ELLIPSE"]);
|
|
@@ -358633,11 +358851,11 @@ function mapCompilerMessages(messages, offset, lines2) {
|
|
|
358633
358851
|
for (const m of messages) {
|
|
358634
358852
|
if (m.type !== "error" && m.type !== "warning") continue;
|
|
358635
358853
|
const line = m.lineNum - offset;
|
|
358636
|
-
const
|
|
358854
|
+
const inside3 = m.lineNum > 0 && line >= 1 && line <= lines2;
|
|
358637
358855
|
out.push({
|
|
358638
|
-
line:
|
|
358639
|
-
column:
|
|
358640
|
-
message:
|
|
358856
|
+
line: inside3 ? line : null,
|
|
358857
|
+
column: inside3 && m.linePos > 0 ? m.linePos : null,
|
|
358858
|
+
message: inside3 ? m.message : harnessMessage(m.message),
|
|
358641
358859
|
severity: m.type === "error" ? "error" : "warning"
|
|
358642
358860
|
});
|
|
358643
358861
|
}
|
|
@@ -359152,9 +359370,9 @@ var init_motion_rich = __esm({
|
|
|
359152
359370
|
if (def.type !== "NUMBER" && def.type !== "COLOR" && def.type !== "IMAGE") throw new ToolError("Only a NUMBER, COLOR or IMAGE property feeds a layer input.");
|
|
359153
359371
|
const layer2 = nodeOrThrow(doc2, op4.layer);
|
|
359154
359372
|
const owner = target2.type === "COMPONENT_SET" ? target2.id : target2.id;
|
|
359155
|
-
let
|
|
359156
|
-
for (let n = layer2; n; n = n.parentId ? doc2.nodes[n.parentId] : void 0) if (n.id === owner)
|
|
359157
|
-
if (!
|
|
359373
|
+
let inside3 = false;
|
|
359374
|
+
for (let n = layer2; n; n = n.parentId ? doc2.nodes[n.parentId] : void 0) if (n.id === owner) inside3 = true;
|
|
359375
|
+
if (!inside3 || layer2.id === owner) throw new ToolError(`"${layer2.name}" is not a layer inside "${target2.name}".`);
|
|
359158
359376
|
const props = layerInputPatch(layer2, op4.name, op4.path);
|
|
359159
359377
|
if (!props) throw new ToolError(`"${layer2.name}" has no ${op4.path}.`);
|
|
359160
359378
|
commitUpdates(ctx2, doc2, /* @__PURE__ */ new Map([[layer2.id, props]]));
|
|
@@ -361284,7 +361502,14 @@ var init_media = __esm({
|
|
|
361284
361502
|
},
|
|
361285
361503
|
run: async (args2) => {
|
|
361286
361504
|
const { listLibraryMedia: listLibraryMedia2 } = await Promise.resolve().then(() => (init_client5(), client_exports3));
|
|
361287
|
-
const
|
|
361505
|
+
const q = { ...args2 };
|
|
361506
|
+
if (!q.workspace) {
|
|
361507
|
+
const { syncStatus: syncStatus2 } = await Promise.resolve().then(() => (init_sync2(), sync_exports2));
|
|
361508
|
+
const link2 = syncStatus2().link;
|
|
361509
|
+
if (!link2) throw new ToolError("This document is not saved to the cloud, so it has no team media library. Pass workspace.");
|
|
361510
|
+
q.workspace = (await listLibraryMedia2({ file: link2.key, limit: 1 })).workspaceId;
|
|
361511
|
+
}
|
|
361512
|
+
const page = await listLibraryMedia2(q);
|
|
361288
361513
|
return { summary: `${page.items.length} media item${page.items.length === 1 ? "" : "s"}${page.nextCursor ? " (more)" : ""}`, data: { workspaceId: page.workspaceId, items: page.items.map(brief3), nextCursor: page.nextCursor } };
|
|
361289
361514
|
}
|
|
361290
361515
|
});
|
|
@@ -401284,7 +401509,6 @@ function placeDesign(doc2, built, source3, size6, name2, at4) {
|
|
|
401284
401509
|
var DESIGN_NAMESPACES, DERIVED2, templateOfBuild;
|
|
401285
401510
|
var init_build3 = __esm({
|
|
401286
401511
|
"lib/agent/design-script/build.ts"() {
|
|
401287
|
-
"use strict";
|
|
401288
401512
|
init_hash();
|
|
401289
401513
|
init_scene_graph();
|
|
401290
401514
|
init_libraries();
|
|
@@ -401314,7 +401538,6 @@ function designFrameOf(doc2, id3) {
|
|
|
401314
401538
|
}
|
|
401315
401539
|
var init_locate = __esm({
|
|
401316
401540
|
"lib/agent/design-script/locate.ts"() {
|
|
401317
|
-
"use strict";
|
|
401318
401541
|
}
|
|
401319
401542
|
});
|
|
401320
401543
|
|
|
@@ -401861,6 +402084,10 @@ async function drive(meta3, start2) {
|
|
|
401861
402084
|
return [...notes, ...runtime.drainParentNotifications()];
|
|
401862
402085
|
},
|
|
401863
402086
|
maxParallel: MAX_PARALLEL_TOOLS,
|
|
402087
|
+
// The loop's default cut every result at 8000 characters AFTER the tool had honoured its own limit, so
|
|
402088
|
+
// export_svg with maxChars 40000 still came back without its last paths and the model could not
|
|
402089
|
+
// rebuild the artwork. Tools bound their own output; this is only the backstop.
|
|
402090
|
+
maxResultChars: MAX_TOOL_RESULT_CHARS,
|
|
401864
402091
|
maxRounds: TURN_MAX_ROUNDS,
|
|
401865
402092
|
modelRetries: 3,
|
|
401866
402093
|
isRecoverable: (err2) => !abort.signal.aborted && isInterruption(err2),
|
|
@@ -401986,7 +402213,7 @@ async function drive(meta3, start2) {
|
|
|
401986
402213
|
useAgentStore.setState({ running: false, resuming: false, abort: null });
|
|
401987
402214
|
}
|
|
401988
402215
|
}
|
|
401989
|
-
var ALWAYS_ALLOWED, MAX_HISTORY_MESSAGES, MAX_PARALLEL_TOOLS, TURN_MAX_ROUNDS, registerTurnTools, specsFor, loopTools, runs, agentRuns, setAgentRuns, RESUME_WINDOW_MS, MAX_INTERRUPTIONS, SUSPEND_RESTART_MS, STOPPED_MESSAGE;
|
|
402216
|
+
var ALWAYS_ALLOWED, MAX_HISTORY_MESSAGES, MAX_PARALLEL_TOOLS, MAX_TOOL_RESULT_CHARS, TURN_MAX_ROUNDS, registerTurnTools, specsFor, loopTools, runs, agentRuns, setAgentRuns, RESUME_WINDOW_MS, MAX_INTERRUPTIONS, SUSPEND_RESTART_MS, STOPPED_MESSAGE;
|
|
401990
402217
|
var init_runner = __esm({
|
|
401991
402218
|
"lib/agent/runner.ts"() {
|
|
401992
402219
|
init_editor_store();
|
|
@@ -402012,6 +402239,7 @@ var init_runner = __esm({
|
|
|
402012
402239
|
ALWAYS_ALLOWED = ["list_skills", "read_skill", "manage_todos", "notify", "get_selection", "task", "await_job", "send_message", "stop_agent", "list_agents", "list_profiles", "read_profile", "ask_user"];
|
|
402013
402240
|
MAX_HISTORY_MESSAGES = 24;
|
|
402014
402241
|
MAX_PARALLEL_TOOLS = 4;
|
|
402242
|
+
MAX_TOOL_RESULT_CHARS = 48e3;
|
|
402015
402243
|
TURN_MAX_ROUNDS = 500;
|
|
402016
402244
|
registerTurnTools = (deps) => {
|
|
402017
402245
|
registerBuiltinTools();
|
|
@@ -407377,7 +407605,6 @@ __export(editor_store_exports, {
|
|
|
407377
407605
|
rebuildVectorData: () => rebuildVectorData,
|
|
407378
407606
|
recoverPointsFromData: () => recoverPointsFromData,
|
|
407379
407607
|
resetLibraryDocuments: () => resetLibraryDocuments,
|
|
407380
|
-
scaleChildrenRecursively: () => scaleChildrenRecursively,
|
|
407381
407608
|
tabPrefsOnly: () => tabPrefsOnly,
|
|
407382
407609
|
useActiveTool: () => useActiveTool,
|
|
407383
407610
|
useCamera: () => useCamera,
|
|
@@ -407550,37 +407777,6 @@ function stripImagePlaceholderFills(nodes, prevNodes, changed) {
|
|
|
407550
407777
|
}
|
|
407551
407778
|
return out ?? nodes;
|
|
407552
407779
|
}
|
|
407553
|
-
function rebuildVectorData(points, closed) {
|
|
407554
|
-
if (points.length < 2) return [];
|
|
407555
|
-
const data = [];
|
|
407556
|
-
data.push("M", points[0].x, points[0].y);
|
|
407557
|
-
for (let i2 = 1; i2 < points.length; i2++) {
|
|
407558
|
-
const prev = points[i2 - 1];
|
|
407559
|
-
const curr = points[i2];
|
|
407560
|
-
if (prev.handleOut && curr.handleIn) {
|
|
407561
|
-
data.push("C", prev.handleOut.x, prev.handleOut.y, curr.handleIn.x, curr.handleIn.y, curr.x, curr.y);
|
|
407562
|
-
} else if (prev.handleOut) {
|
|
407563
|
-
data.push("Q", prev.handleOut.x, prev.handleOut.y, curr.x, curr.y);
|
|
407564
|
-
} else if (curr.handleIn) {
|
|
407565
|
-
data.push("Q", curr.handleIn.x, curr.handleIn.y, curr.x, curr.y);
|
|
407566
|
-
} else {
|
|
407567
|
-
data.push("L", curr.x, curr.y);
|
|
407568
|
-
}
|
|
407569
|
-
}
|
|
407570
|
-
if (closed) {
|
|
407571
|
-
const prev = points[points.length - 1];
|
|
407572
|
-
const curr = points[0];
|
|
407573
|
-
if (prev.handleOut && curr.handleIn) {
|
|
407574
|
-
data.push("C", prev.handleOut.x, prev.handleOut.y, curr.handleIn.x, curr.handleIn.y, curr.x, curr.y);
|
|
407575
|
-
} else if (prev.handleOut) {
|
|
407576
|
-
data.push("Q", prev.handleOut.x, prev.handleOut.y, curr.x, curr.y);
|
|
407577
|
-
} else if (curr.handleIn) {
|
|
407578
|
-
data.push("Q", curr.handleIn.x, curr.handleIn.y, curr.x, curr.y);
|
|
407579
|
-
}
|
|
407580
|
-
data.push("Z");
|
|
407581
|
-
}
|
|
407582
|
-
return data;
|
|
407583
|
-
}
|
|
407584
407780
|
function fixCorruptedVectors(doc2) {
|
|
407585
407781
|
let changed = false;
|
|
407586
407782
|
const newNodes = { ...doc2.nodes };
|
|
@@ -407730,30 +407926,6 @@ function recoverPointsFromData(data) {
|
|
|
407730
407926
|
}
|
|
407731
407927
|
return points;
|
|
407732
407928
|
}
|
|
407733
|
-
function scaleChildrenRecursively(doc2, parentId, scaleX, scaleY) {
|
|
407734
|
-
const parent = doc2.nodes[parentId];
|
|
407735
|
-
if (!parent || !parent.childIds) return doc2;
|
|
407736
|
-
const newDoc = { ...doc2, nodes: { ...doc2.nodes } };
|
|
407737
|
-
const processNode = (nodeId2) => {
|
|
407738
|
-
const node2 = newDoc.nodes[nodeId2];
|
|
407739
|
-
if (!node2) return;
|
|
407740
|
-
const updates = {
|
|
407741
|
-
x: node2.x * scaleX,
|
|
407742
|
-
y: node2.y * scaleY,
|
|
407743
|
-
width: node2.width * scaleX,
|
|
407744
|
-
height: node2.height * scaleY
|
|
407745
|
-
};
|
|
407746
|
-
if (node2.type === "TEXT") {
|
|
407747
|
-
updates.fontSize = (node2.fontSize ?? 16) * Math.min(scaleX, scaleY);
|
|
407748
|
-
}
|
|
407749
|
-
newDoc.nodes[nodeId2] = { ...node2, ...updates };
|
|
407750
|
-
if (node2.childIds) {
|
|
407751
|
-
node2.childIds.forEach(processNode);
|
|
407752
|
-
}
|
|
407753
|
-
};
|
|
407754
|
-
parent.childIds.forEach(processNode);
|
|
407755
|
-
return newDoc;
|
|
407756
|
-
}
|
|
407757
407929
|
function placeInstance(document2, mainComponentId, pageId2, x2, y) {
|
|
407758
407930
|
const main2 = document2.nodes[mainComponentId];
|
|
407759
407931
|
if (!main2 || main2.type !== "COMPONENT") return null;
|
|
@@ -409360,10 +409532,10 @@ var init_editor_store = __esm({
|
|
|
409360
409532
|
if ("childIds" in node2 && node2.childIds.length > 0) {
|
|
409361
409533
|
newDoc = applyConstraints(newDoc, id3, node2.width, node2.height, newWidth, newHeight);
|
|
409362
409534
|
}
|
|
409363
|
-
if (node2.type === "GROUP" && node2.width > 0 && node2.height > 0) {
|
|
409364
|
-
const
|
|
409365
|
-
|
|
409366
|
-
|
|
409535
|
+
if ((node2.type === "GROUP" || node2.type === "VECTOR") && node2.width > 0 && node2.height > 0) {
|
|
409536
|
+
for (const [pid, patch2] of scaleSubtreePatches(newDoc.nodes, id3, newWidth / node2.width, newHeight / node2.height)) {
|
|
409537
|
+
newDoc = updateNode(newDoc, pid, patch2);
|
|
409538
|
+
}
|
|
409367
409539
|
} else if (node2.type === "TABLE" && node2.width > 0 && node2.height > 0) {
|
|
409368
409540
|
const table3 = node2;
|
|
409369
409541
|
const totalW = (table3.colWidths || []).reduce((a, b) => a + b, 0) || 1;
|
|
@@ -410372,23 +410544,35 @@ var init_editor_store = __esm({
|
|
|
410372
410544
|
const geo = multiPolyToVectorGeometry(mp);
|
|
410373
410545
|
if (!geo) return;
|
|
410374
410546
|
const first2 = doc2.nodes[state.selection[0]];
|
|
410547
|
+
const firstFills = (id3) => {
|
|
410548
|
+
const n = doc2.nodes[id3];
|
|
410549
|
+
if (!n) return void 0;
|
|
410550
|
+
if (n.fills?.length && n.type !== "GROUP") return n.fills;
|
|
410551
|
+
for (const c2 of n.childIds ?? []) {
|
|
410552
|
+
const f2 = firstFills(c2);
|
|
410553
|
+
if (f2) return f2;
|
|
410554
|
+
}
|
|
410555
|
+
return void 0;
|
|
410556
|
+
};
|
|
410557
|
+
const fills = state.selection.map(firstFills).find(Boolean);
|
|
410375
410558
|
const vectorNode = createVector({
|
|
410376
410559
|
...geo,
|
|
410377
|
-
fills:
|
|
410560
|
+
fills: fills ?? [{ type: "SOLID", color: { r: 0.85, g: 0.85, b: 0.85, a: 1 }, visible: true }],
|
|
410378
410561
|
strokes: [],
|
|
410379
410562
|
fillRule: "EVENODD",
|
|
410380
410563
|
name: state.selection.length > 1 ? "Flattened" : `${first2?.name ?? "Vector"} (flattened)`
|
|
410381
410564
|
});
|
|
410382
410565
|
doc2 = addNode(doc2, vectorNode, state.currentPageId);
|
|
410566
|
+
const parentId = first2?.parentId;
|
|
410567
|
+
if (parentId && parentId !== state.currentPageId && doc2.nodes[parentId]) {
|
|
410568
|
+
const placed2 = placementUnder(doc2, vectorNode.id, parentId);
|
|
410569
|
+
if (placed2) doc2 = reparentNode(updateNode(doc2, vectorNode.id, placed2), vectorNode.id, parentId);
|
|
410570
|
+
}
|
|
410383
410571
|
state.selection.forEach((id3) => {
|
|
410384
410572
|
if (doc2.nodes[id3]) doc2 = removeNode(doc2, id3);
|
|
410385
410573
|
});
|
|
410386
|
-
|
|
410387
|
-
set4({
|
|
410388
|
-
document: doc2,
|
|
410389
|
-
history: pushCommand(state.history, command),
|
|
410390
|
-
selection: [vectorNode.id]
|
|
410391
|
-
});
|
|
410574
|
+
if (documentBefore !== doc2) get4().commitDocument(doc2, "Flatten selection");
|
|
410575
|
+
set4({ selection: [vectorNode.id] });
|
|
410392
410576
|
},
|
|
410393
410577
|
joinPaths: () => {
|
|
410394
410578
|
const state = get4();
|
|
@@ -414100,7 +414284,7 @@ init_resources();
|
|
|
414100
414284
|
init_desktop();
|
|
414101
414285
|
init_hypery();
|
|
414102
414286
|
import { createInterface } from "node:readline";
|
|
414103
|
-
var VERSION2 = "0.53.
|
|
414287
|
+
var VERSION2 = "0.53.2";
|
|
414104
414288
|
var HELP = `popcraft ${VERSION2} \u2014 the PopCraft command line
|
|
414105
414289
|
|
|
414106
414290
|
Files (headless, on .popcraft files):
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@popcraft/cli",
|
|
3
|
-
"version": "0.53.
|
|
3
|
+
"version": "0.53.2",
|
|
4
4
|
"description": "The PopCraft command line: edit .popcraft files headlessly, call the REST API, publish to the marketplace and manage the desktop app's local plugins, themes, fonts, skills and agents.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://popcraft.app/docs/api/cli",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"esbuild": "0.28.2"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@popcraft/kit": "0.53.
|
|
37
|
+
"@popcraft/kit": "0.53.2"
|
|
38
38
|
},
|
|
39
39
|
"scripts": {
|
|
40
40
|
"build": "node build.mjs",
|