@popcraft/cli 0.47.0 → 0.48.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/dist/popcraft.mjs +194 -42
- 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.
|
|
1199
|
+
const headers = { "user-agent": `popcraft-cli/${"0.48.0"}`, ...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 {
|
|
@@ -33233,6 +33233,7 @@ var init_en2 = __esm({
|
|
|
33233
33233
|
"designPanel.instanceSwap": "Instance swap",
|
|
33234
33234
|
"designPanel.italic": "Italic",
|
|
33235
33235
|
"designPanel.join": "Join",
|
|
33236
|
+
"designPanel.keepProportions": "Keep proportions (height follows width)",
|
|
33236
33237
|
"designPanel.language": "Language",
|
|
33237
33238
|
"designPanel.lastFrame": "Last frame",
|
|
33238
33239
|
"designPanel.layer": "Layer",
|
|
@@ -97957,6 +97958,11 @@ function applyAutoLayout(doc2) {
|
|
|
97957
97958
|
} else {
|
|
97958
97959
|
let height = node2.height;
|
|
97959
97960
|
let width = node2.width;
|
|
97961
|
+
const ar = node2.aspectRatio;
|
|
97962
|
+
if (ar && ar > 0 && node2.layoutSizingVertical !== "FILL" && Math.abs(width / ar - height) > 0.01) {
|
|
97963
|
+
height = Math.round(width / ar * 1e3) / 1e3;
|
|
97964
|
+
cloneNode(nodeId2).height = height;
|
|
97965
|
+
}
|
|
97960
97966
|
if (node2.type === "INSTANCE") {
|
|
97961
97967
|
const h = instanceContentHeight(newNodes, nodeId2);
|
|
97962
97968
|
if (h !== null && Math.abs(h - height) > 0.5) {
|
|
@@ -98085,6 +98091,8 @@ function applyAutoLayout(doc2) {
|
|
|
98085
98091
|
const r = Math.floor(index2 / actualCols);
|
|
98086
98092
|
if (child.layoutSizingHorizontal === "FILL") child.width = clampedWidth(colW[c2], child);
|
|
98087
98093
|
if (child.layoutSizingVertical === "FILL") child.height = clampedHeight(rowH[r], child);
|
|
98094
|
+
keepAspect(child);
|
|
98095
|
+
fitWipe(child, newNodes, cloneNode);
|
|
98088
98096
|
const cellX = colX[c2];
|
|
98089
98097
|
const cellY = rowY[r];
|
|
98090
98098
|
child.x = cellX;
|
|
@@ -98123,6 +98131,8 @@ function applyAutoLayout(doc2) {
|
|
|
98123
98131
|
if (child.layoutSizingVertical === "FILL") child.height = clampedHeight(fillPrimarySize, child);
|
|
98124
98132
|
if (child.layoutSizingHorizontal === "FILL") child.width = clampedWidth(Math.max(0, frame3.width - paddingX), child);
|
|
98125
98133
|
}
|
|
98134
|
+
keepAspect(child);
|
|
98135
|
+
fitWipe(child, newNodes, cloneNode);
|
|
98126
98136
|
});
|
|
98127
98137
|
if (wraps(frame3)) {
|
|
98128
98138
|
const lines2 = wrapLines(frame3, childIds, (id3) => ({ intrinsicWidth: newNodes[id3].width, intrinsicHeight: newNodes[id3].height }));
|
|
@@ -98191,7 +98201,12 @@ function applyAutoLayout(doc2) {
|
|
|
98191
98201
|
});
|
|
98192
98202
|
}
|
|
98193
98203
|
}
|
|
98194
|
-
|
|
98204
|
+
let aspect = false;
|
|
98205
|
+
for (const id3 in newNodes) if (newNodes[id3].aspectRatio) {
|
|
98206
|
+
aspect = true;
|
|
98207
|
+
break;
|
|
98208
|
+
}
|
|
98209
|
+
for (let pass = 0; pass < (aspect ? 2 : 1); pass++) autoLayoutRoots.forEach((root2) => {
|
|
98195
98210
|
measureNode(root2.id);
|
|
98196
98211
|
layoutNode(root2.id);
|
|
98197
98212
|
});
|
|
@@ -98204,6 +98219,21 @@ function applyAutoLayout(doc2) {
|
|
|
98204
98219
|
}
|
|
98205
98220
|
return { ...doc2, nodes: newNodes };
|
|
98206
98221
|
}
|
|
98222
|
+
function keepAspect(n) {
|
|
98223
|
+
if (n.aspectRatio > 0 && n.layoutSizingVertical !== "FILL") n.height = Math.round(n.width / n.aspectRatio * 1e3) / 1e3;
|
|
98224
|
+
}
|
|
98225
|
+
function fitWipe(group2, nodes, clone2) {
|
|
98226
|
+
if (group2.type !== "GROUP" || !group2.isMaskGroup || !group2.childIds.some((id3) => nodes[id3]?.isMask && nodes[id3]?.name === "Wipe mask")) return;
|
|
98227
|
+
const w = group2.layoutSizingHorizontal === "FILL", h = group2.layoutSizingVertical === "FILL" || group2.aspectRatio > 0;
|
|
98228
|
+
if (!w && !h) return;
|
|
98229
|
+
for (const id3 of group2.childIds) {
|
|
98230
|
+
const c2 = nodes[id3];
|
|
98231
|
+
if (!c2 || (!w || c2.width === group2.width) && (!h || c2.height === group2.height)) continue;
|
|
98232
|
+
const n = clone2(id3);
|
|
98233
|
+
if (w) n.width = group2.width;
|
|
98234
|
+
if (h) n.height = group2.height;
|
|
98235
|
+
}
|
|
98236
|
+
}
|
|
98207
98237
|
function wraps(frame3) {
|
|
98208
98238
|
if (frame3.layoutWrap !== "WRAP" || frame3.layoutMode === "GRID") return false;
|
|
98209
98239
|
return frame3.layoutMode === "HORIZONTAL" ? frame3.layoutSizingHorizontal !== "HUG" : frame3.layoutSizingVertical !== "HUG";
|
|
@@ -246764,6 +246794,45 @@ function lineWidth(line, family, weight, fontSize, italic, shaping) {
|
|
|
246764
246794
|
}
|
|
246765
246795
|
return units * fontSize;
|
|
246766
246796
|
}
|
|
246797
|
+
function unitAdvances(line, family, weight, fontSize, italic, shaping) {
|
|
246798
|
+
const out = new Array(line.length).fill(0);
|
|
246799
|
+
if (!line) return out;
|
|
246800
|
+
const share = (start2, len3, em) => {
|
|
246801
|
+
const n = Math.max(1, len3);
|
|
246802
|
+
for (let k2 = 0; k2 < n && start2 + k2 < line.length; k2++) out[start2 + k2] += em * fontSize / n;
|
|
246803
|
+
};
|
|
246804
|
+
const place4 = (glyphs, upem, offset, notdef) => {
|
|
246805
|
+
for (const g of glyphs) {
|
|
246806
|
+
if (notdef && g.gid === 0) {
|
|
246807
|
+
if (g.clusterLength === 0) continue;
|
|
246808
|
+
const text = line.slice(offset + g.clusterStart, offset + g.clusterStart + g.clusterLength);
|
|
246809
|
+
share(offset + g.clusterStart, g.clusterLength, fallbackEm(text, family, weight, italic));
|
|
246810
|
+
continue;
|
|
246811
|
+
}
|
|
246812
|
+
share(offset + g.clusterStart, g.clusterLength, g.xAdvance / upem);
|
|
246813
|
+
}
|
|
246814
|
+
};
|
|
246815
|
+
const shaped = shapeRun(line, family, italic, weight, shaping?.features, shaping?.variations);
|
|
246816
|
+
if (shaped) {
|
|
246817
|
+
place4(shaped.glyphs, shaped.unitsPerEm, 0, true);
|
|
246818
|
+
return out;
|
|
246819
|
+
}
|
|
246820
|
+
const fb = shapeFallback(line, family, italic, weight, shaping?.features);
|
|
246821
|
+
if (fb === "loading") {
|
|
246822
|
+
let i2 = 0;
|
|
246823
|
+
for (const ch of line) {
|
|
246824
|
+
share(i2, ch.length, fallbackEm(ch, family, weight, italic));
|
|
246825
|
+
i2 += ch.length;
|
|
246826
|
+
}
|
|
246827
|
+
return out;
|
|
246828
|
+
}
|
|
246829
|
+
for (const item of fb.items) place4(item.shaped.glyphs, item.shaped.unitsPerEm, item.start, false);
|
|
246830
|
+
for (const i2 of fb.missing) {
|
|
246831
|
+
const c2 = line.charCodeAt(i2);
|
|
246832
|
+
if (!(c2 >= 56320 && c2 <= 57343 && i2 > 0)) out[i2] += 0.5 * fontSize;
|
|
246833
|
+
}
|
|
246834
|
+
return out;
|
|
246835
|
+
}
|
|
246767
246836
|
function fallbackEm(text, family, weight, italic, strict = false) {
|
|
246768
246837
|
let em = 0;
|
|
246769
246838
|
for (const ch of text) {
|
|
@@ -246795,24 +246864,35 @@ function casedText(text, textCase) {
|
|
|
246795
246864
|
function measureAutoWidth(t3) {
|
|
246796
246865
|
return measureTextWidth(casedText(t3.characters ?? "", t3.textCase), t3.fontFamily, t3.fontWeight, t3.fontSize, t3.fontStyle, t3.letterSpacing ?? 0, { features: t3.fontFeatures, variations: t3.fontVariations });
|
|
246797
246866
|
}
|
|
246798
|
-
function estimateTextHeight(characters, width, family, weight, size6, lineHeight, wraps2 = true, letterSpacing = 0) {
|
|
246799
|
-
const lh2 = lineHeight === "AUTO" ? size6 * 1.
|
|
246800
|
-
const
|
|
246867
|
+
function estimateTextHeight(characters, width, family, weight, size6, lineHeight, wraps2 = true, letterSpacing = 0, setting = {}) {
|
|
246868
|
+
const lh2 = lineHeight === "AUTO" ? size6 * 1.2 : lineHeight;
|
|
246869
|
+
const italic = setting.fontStyle === "italic";
|
|
246801
246870
|
let lines2 = 0;
|
|
246802
246871
|
for (const para of characters.split("\n")) {
|
|
246803
|
-
|
|
246804
|
-
if (wraps2
|
|
246805
|
-
|
|
246806
|
-
|
|
246807
|
-
|
|
246808
|
-
|
|
246809
|
-
|
|
246810
|
-
|
|
246872
|
+
lines2++;
|
|
246873
|
+
if (!wraps2 || !para) continue;
|
|
246874
|
+
const adv = unitAdvances(para, family, weight, size6, italic, setting.shaping);
|
|
246875
|
+
let start2 = 0, w = 0, lastSpace = -1;
|
|
246876
|
+
for (let i2 = 0; i2 < para.length; i2++) {
|
|
246877
|
+
const a = adv[i2] + letterSpacing;
|
|
246878
|
+
const space = para[i2] === " ";
|
|
246879
|
+
if (!space && w + a > width && lastSpace !== -1 && start2 < lastSpace) {
|
|
246880
|
+
lines2++;
|
|
246881
|
+
start2 = lastSpace + 1;
|
|
246882
|
+
w = 0;
|
|
246883
|
+
for (let j = start2; j <= i2; j++) w += adv[j] + letterSpacing;
|
|
246884
|
+
lastSpace = -1;
|
|
246885
|
+
} else {
|
|
246886
|
+
if (space) lastSpace = i2;
|
|
246887
|
+
w += a;
|
|
246888
|
+
}
|
|
246811
246889
|
}
|
|
246812
|
-
lines2 += n;
|
|
246813
246890
|
}
|
|
246814
246891
|
return Math.max(lh2, lines2 * lh2);
|
|
246815
246892
|
}
|
|
246893
|
+
function textSetting(t3) {
|
|
246894
|
+
return { fontStyle: t3.fontStyle, shaping: { features: t3.fontFeatures, variations: t3.fontVariations } };
|
|
246895
|
+
}
|
|
246816
246896
|
var init_measure = __esm({
|
|
246817
246897
|
"lib/engine/text/measure.ts"() {
|
|
246818
246898
|
"use strict";
|
|
@@ -246833,7 +246913,7 @@ function autoTextBounds(node2, styles) {
|
|
|
246833
246913
|
const chars = casedText(resolved.characters || "", resolved.textCase);
|
|
246834
246914
|
const family = resolved.fontFamily || "Inter", weight = resolved.fontWeight || 400, size6 = resolved.fontSize || 16;
|
|
246835
246915
|
const width = hugs2 ? Math.max(measureAutoWidth({ ...resolved, fontFamily: family, fontWeight: weight, fontSize: size6 }) || size6, 10) : node2.width;
|
|
246836
|
-
const estimate2 = estimateTextHeight(chars, width, family, weight, size6, resolved.lineHeight ?? "AUTO", !hugs2, resolved.letterSpacing || 0);
|
|
246916
|
+
const estimate2 = estimateTextHeight(chars, width, family, weight, size6, resolved.lineHeight ?? "AUTO", !hugs2, resolved.letterSpacing || 0, textSetting(resolved));
|
|
246837
246917
|
return { width, height: hugs2 ? estimate2 : Math.max(node2.height, estimate2) };
|
|
246838
246918
|
}
|
|
246839
246919
|
var init_text_bounds = __esm({
|
|
@@ -252457,7 +252537,6 @@ function resizeWindow(doc2, target2, rect) {
|
|
|
252457
252537
|
}
|
|
252458
252538
|
var init_crop = __esm({
|
|
252459
252539
|
"lib/editor/crop.ts"() {
|
|
252460
|
-
"use strict";
|
|
252461
252540
|
init_dist_node();
|
|
252462
252541
|
init_scene_graph();
|
|
252463
252542
|
init_photo_frames();
|
|
@@ -256954,7 +257033,6 @@ function followPeers(peers) {
|
|
|
256954
257033
|
var PALETTE, usePresence, awareness, CURSOR_SEND_MS, VIEWPORT_SEND_MS, cursorTimer, pendingCursor, sentCursor, EMOTE_MS, lastFollowCamera;
|
|
256955
257034
|
var init_presence = __esm({
|
|
256956
257035
|
"lib/collab/presence.ts"() {
|
|
256957
|
-
"use strict";
|
|
256958
257036
|
init_esm();
|
|
256959
257037
|
init_editor_store();
|
|
256960
257038
|
init_status_announcements();
|
|
@@ -259138,7 +259216,11 @@ function ensureWipeMask(nodes, id3, hostFrameId) {
|
|
|
259138
259216
|
childIds: [maskId, id3],
|
|
259139
259217
|
blendMode: "NORMAL",
|
|
259140
259218
|
isMaskGroup: true,
|
|
259141
|
-
...n.layoutPositioning ? { layoutPositioning: n.layoutPositioning } : {}
|
|
259219
|
+
...n.layoutPositioning ? { layoutPositioning: n.layoutPositioning } : {},
|
|
259220
|
+
// A picture that keeps its proportions (a page's content picture) is wiped in its place in the layout: the group
|
|
259221
|
+
// fills and keeps proportions as the picture did, and the layout sizes what it holds to it (lib/document/auto-layout.ts
|
|
259222
|
+
// `fitWipe`), so a phone scales it rather than keeping the desktop's width.
|
|
259223
|
+
...n.aspectRatio ? Object.fromEntries(["layoutSizingHorizontal", "layoutSizingVertical", "aspectRatio"].filter((k2) => n[k2] !== void 0).map((k2) => [k2, n[k2]])) : {}
|
|
259142
259224
|
};
|
|
259143
259225
|
const moved3 = { ...n, parentId: gid, x: 0, y: 0, motion: shiftPositionKeys(n.motion, -n.x, -n.y) };
|
|
259144
259226
|
if (!moved3.motion) delete moved3.motion;
|
|
@@ -261041,11 +261123,32 @@ function breakpointDocument(doc2, id3) {
|
|
|
261041
261123
|
const width = isScreen(doc2, n) && over2?.width === void 0 ? { width: bp.previewWidth } : null;
|
|
261042
261124
|
if (over2 || width) nodes[nid] = { ...n, ...over2, ...width };
|
|
261043
261125
|
}
|
|
261044
|
-
const view2 = applyAutoLayout({ ...doc2, nodes });
|
|
261126
|
+
const view2 = rewrapped(doc2, applyAutoLayout({ ...doc2, nodes }));
|
|
261045
261127
|
const forDoc = viewMemo.get(doc2) ?? viewMemo.set(doc2, /* @__PURE__ */ new Map()).get(doc2);
|
|
261046
261128
|
forDoc.set(id3, view2);
|
|
261047
261129
|
return view2;
|
|
261048
261130
|
}
|
|
261131
|
+
function rewrapped(doc2, view2) {
|
|
261132
|
+
for (let pass = 0; pass < 3; pass++) {
|
|
261133
|
+
let nodes = null;
|
|
261134
|
+
for (const id3 in view2.nodes) {
|
|
261135
|
+
const n = view2.nodes[id3], was = doc2.nodes[id3];
|
|
261136
|
+
if (n.type !== "TEXT" || !n.visible || !was) continue;
|
|
261137
|
+
const t3 = n;
|
|
261138
|
+
if (t3.textAutoResize === "NONE") continue;
|
|
261139
|
+
if (Math.abs(t3.width - was.width) < 0.5 && t3.textStyleId === was.textStyleId && t3.fontSize === was.fontSize && t3.textAutoResize === was.textAutoResize) continue;
|
|
261140
|
+
const m = measureTextLayout(resolveTextNodeStyles(t3, doc2.styles ?? {}));
|
|
261141
|
+
if (!m) continue;
|
|
261142
|
+
const width = t3.textAutoResize === "WIDTH_AND_HEIGHT" ? m.width : t3.width;
|
|
261143
|
+
if (Math.abs(m.height - t3.height) < 0.5 && Math.abs(width - t3.width) < 0.5) continue;
|
|
261144
|
+
nodes ??= { ...view2.nodes };
|
|
261145
|
+
nodes[id3] = { ...t3, width, height: m.height };
|
|
261146
|
+
}
|
|
261147
|
+
if (!nodes) break;
|
|
261148
|
+
view2 = applyAutoLayout({ ...view2, nodes });
|
|
261149
|
+
}
|
|
261150
|
+
return view2;
|
|
261151
|
+
}
|
|
261049
261152
|
function withOverrides(node2, id3, overrides2) {
|
|
261050
261153
|
const next2 = { ...node2.responsive };
|
|
261051
261154
|
if (Object.keys(overrides2).length) next2[id3] = overrides2;
|
|
@@ -261081,8 +261184,9 @@ function laidOut(nodes, n, key5) {
|
|
|
261081
261184
|
const inFlow3 = !!parent && parent.layoutMode !== void 0 && parent.layoutMode !== "NONE" && s.layoutPositioning !== "ABSOLUTE";
|
|
261082
261185
|
const lays = own2.layoutMode !== void 0 && own2.layoutMode !== "NONE";
|
|
261083
261186
|
if (key5 === "x" || key5 === "y") return inFlow3;
|
|
261084
|
-
|
|
261085
|
-
if (key5 === "
|
|
261187
|
+
const fills = (sizing3) => sizing3 === "FILL" && s.layoutPositioning !== "ABSOLUTE";
|
|
261188
|
+
if (key5 === "width") return fills(s.layoutSizingHorizontal) || s.layoutSizingHorizontal === "HUG" && (lays || n.type === "TEXT");
|
|
261189
|
+
if (key5 === "height") return fills(s.layoutSizingVertical) || s.layoutSizingVertical === "HUG" && (lays || n.type === "TEXT") || n.type === "TEXT" && n.textAutoResize !== "NONE";
|
|
261086
261190
|
return false;
|
|
261087
261191
|
}
|
|
261088
261192
|
function breakpointResult(rest, baked, edited, id3) {
|
|
@@ -261123,7 +261227,9 @@ function foldVariant(doc2, masterId, variantId, id3) {
|
|
|
261123
261227
|
const restyled = variant.textStyleId !== master.textStyleId;
|
|
261124
261228
|
for (const k2 of RESPONSIVE_PROPS) {
|
|
261125
261229
|
if (isRoot && (k2 === "x" || k2 === "y" || k2 === "width")) continue;
|
|
261126
|
-
const
|
|
261230
|
+
const set4 = variant[k2];
|
|
261231
|
+
const inherited = k2 in UNSET && (master[k2] !== void 0 || overridesAt(master, doc2, id3)?.[k2] !== void 0);
|
|
261232
|
+
const value3 = set4 ?? (inherited ? UNSET[k2] : void 0);
|
|
261127
261233
|
if (value3 === void 0 || laidOut(doc2.nodes, variant, k2)) continue;
|
|
261128
261234
|
if ((k2 === "fontSize" || k2 === "lineHeight") && restyled) continue;
|
|
261129
261235
|
props[k2] = value3;
|
|
@@ -261149,11 +261255,13 @@ function setBreakpoints(doc2, list2) {
|
|
|
261149
261255
|
}
|
|
261150
261256
|
return nodes ? { ...next2, nodes } : next2;
|
|
261151
261257
|
}
|
|
261152
|
-
var DEFAULT_BREAKPOINTS, RESPONSIVE_PROPS, RESPONSIVE, isBaseBreakpoint, same2, ownOverrides, isScreen, viewMemo;
|
|
261258
|
+
var DEFAULT_BREAKPOINTS, RESPONSIVE_PROPS, RESPONSIVE, isBaseBreakpoint, UNSET, same2, ownOverrides, isScreen, viewMemo;
|
|
261153
261259
|
var init_breakpoints = __esm({
|
|
261154
261260
|
"lib/document/breakpoints.ts"() {
|
|
261155
261261
|
"use strict";
|
|
261156
261262
|
init_auto_layout();
|
|
261263
|
+
init_instance_layout();
|
|
261264
|
+
init_text_styles();
|
|
261157
261265
|
DEFAULT_BREAKPOINTS = [
|
|
261158
261266
|
{ id: "desktop", name: "Desktop", maxWidth: null, previewWidth: 1280 },
|
|
261159
261267
|
{ id: "tablet", name: "Tablet", maxWidth: 1024, previewWidth: 834 },
|
|
@@ -261183,10 +261291,24 @@ var init_breakpoints = __esm({
|
|
|
261183
261291
|
"fontSize",
|
|
261184
261292
|
"lineHeight",
|
|
261185
261293
|
"textAlign",
|
|
261186
|
-
"textStyleId"
|
|
261294
|
+
"textStyleId",
|
|
261295
|
+
"scaleX",
|
|
261296
|
+
"scaleY",
|
|
261297
|
+
"anchorX",
|
|
261298
|
+
"anchorY",
|
|
261299
|
+
"rotation",
|
|
261300
|
+
"cornerRadius",
|
|
261301
|
+
"textAutoResize",
|
|
261302
|
+
"paths",
|
|
261303
|
+
"translateX",
|
|
261304
|
+
"translateY",
|
|
261305
|
+
"z",
|
|
261306
|
+
"rotateX",
|
|
261307
|
+
"rotateY"
|
|
261187
261308
|
];
|
|
261188
261309
|
RESPONSIVE = new Set(RESPONSIVE_PROPS);
|
|
261189
261310
|
isBaseBreakpoint = (doc2, id3) => !id3 || breakpointsOf(doc2)[0].id === id3 || !breakpointsOf(doc2).some((b) => b.id === id3);
|
|
261311
|
+
UNSET = { scaleX: 1, scaleY: 1, anchorX: 0.5, anchorY: 0.5, rotation: 0, translateX: 0, translateY: 0, z: 0, rotateX: 0, rotateY: 0 };
|
|
261190
261312
|
same2 = (a, b) => a === b || typeof a === "object" && typeof b === "object" && JSON.stringify(a) === JSON.stringify(b);
|
|
261191
261313
|
ownOverrides = (node2, id3) => Object.keys(node2?.responsive?.[id3] ?? {});
|
|
261192
261314
|
isScreen = (doc2, n) => n.type === "FRAME" && doc2.nodes[n.parentId ?? ""]?.type === "PAGE";
|
|
@@ -262989,7 +263111,6 @@ function planEntryAction({ home }) {
|
|
|
262989
263111
|
var STORAGE_KEY2, useHyperyTeam, TEAM_PROMPT_ENABLED, TEAM_PROMPTED_KEY, PROMPTED_KEY, useTeamPrompt, started;
|
|
262990
263112
|
var init_team = __esm({
|
|
262991
263113
|
"lib/client/cloud/team.ts"() {
|
|
262992
|
-
"use strict";
|
|
262993
263114
|
init_esm();
|
|
262994
263115
|
init_api4();
|
|
262995
263116
|
init_session();
|
|
@@ -306672,7 +306793,6 @@ function decodeSource(key5, label3) {
|
|
|
306672
306793
|
var DECODE_CACHE_BYTES, cache7, pending4, held, sizeOf, lengths, decodedLengths, DECODE_TIMEOUT_MS, decodedAudio, decodedSource, pcmOf;
|
|
306673
306794
|
var init_audio_decode = __esm({
|
|
306674
306795
|
"lib/motion/audio-decode.ts"() {
|
|
306675
|
-
"use strict";
|
|
306676
306796
|
init_media_store();
|
|
306677
306797
|
init_audio_plan();
|
|
306678
306798
|
init_time_stretch();
|
|
@@ -310059,7 +310179,6 @@ function importSVGFile(file2, document2, parentId) {
|
|
|
310059
310179
|
var ENTITIES, decode3, I, mul2, apply2, scaleOf, NUM2, nums, near, NAMED, INHERITED, PRESENTATION, len2, CAP, JOIN, SKIPPED, refId;
|
|
310060
310180
|
var init_svg_import = __esm({
|
|
310061
310181
|
"lib/io/svg-import.ts"() {
|
|
310062
|
-
"use strict";
|
|
310063
310182
|
init_dist_node();
|
|
310064
310183
|
init_types();
|
|
310065
310184
|
ENTITIES = { amp: "&", lt: "<", gt: ">", quot: '"', apos: "'", nbsp: "\xA0" };
|
|
@@ -311452,6 +311571,7 @@ function startCloudSync() {
|
|
|
311452
311571
|
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;
|
|
311453
311572
|
var init_sync2 = __esm({
|
|
311454
311573
|
"lib/client/cloud/sync.ts"() {
|
|
311574
|
+
"use strict";
|
|
311455
311575
|
init_paint_repair();
|
|
311456
311576
|
init_migrate();
|
|
311457
311577
|
init_view();
|
|
@@ -311721,7 +311841,7 @@ var init_text_measurer = __esm({
|
|
|
311721
311841
|
const width = node2.textAutoResize === "WIDTH_AND_HEIGHT" ? Math.max(1, Math.ceil(measureAutoWidth(node2))) : node2.width;
|
|
311722
311842
|
return {
|
|
311723
311843
|
width,
|
|
311724
|
-
height: Math.round(estimateTextHeight(characters, width, node2.fontFamily, node2.fontWeight, node2.fontSize, node2.lineHeight ?? "AUTO", node2.textAutoResize !== "WIDTH_AND_HEIGHT", node2.letterSpacing ?? 0))
|
|
311844
|
+
height: Math.round(estimateTextHeight(characters, width, node2.fontFamily, node2.fontWeight, node2.fontSize, node2.lineHeight ?? "AUTO", node2.textAutoResize !== "WIDTH_AND_HEIGHT", node2.letterSpacing ?? 0, textSetting(node2)))
|
|
311725
311845
|
};
|
|
311726
311846
|
};
|
|
311727
311847
|
}
|
|
@@ -313504,7 +313624,7 @@ function layoutTextUncached(node2, atlas, cameraZoom = 1) {
|
|
|
313504
313624
|
}
|
|
313505
313625
|
}
|
|
313506
313626
|
if (hyphenated) {
|
|
313507
|
-
} else if (currentIndent + lineWidth2 + advance > maxWidth2 && lastSpaceIndex !== -1 && lineStartIndex < lastSpaceIndex) {
|
|
313627
|
+
} else if (!isSpace2 && currentIndent + lineWidth2 + advance > maxWidth2 && lastSpaceIndex !== -1 && lineStartIndex < lastSpaceIndex) {
|
|
313508
313628
|
let wrappedLineHeight = 0;
|
|
313509
313629
|
for (let j = lineStartIndex; j < lastSpaceIndex; j++) {
|
|
313510
313630
|
const lh3 = resolvedStyles[j].lineHeight === "AUTO" ? resolvedStyles[j].fontSize * 1.2 : resolvedStyles[j].lineHeight;
|
|
@@ -317278,6 +317398,7 @@ async function selectionReferenceImages(doc2, selection, opts = {}) {
|
|
|
317278
317398
|
var FIT_QUALITIES, FIT_SCALES, blobToDataUrl;
|
|
317279
317399
|
var init_reference_images = __esm({
|
|
317280
317400
|
"lib/ai/reference-images.ts"() {
|
|
317401
|
+
"use strict";
|
|
317281
317402
|
init_export();
|
|
317282
317403
|
init_selection_bounds();
|
|
317283
317404
|
init_renderer_registry();
|
|
@@ -318120,7 +318241,6 @@ function agentToolList() {
|
|
|
318120
318241
|
var AGENT_CAPABILITIES, legacyCommandId, legacyTools, blobToDataUrl3, provided, legacyTool, legacyToolList;
|
|
318121
318242
|
var init_agent = __esm({
|
|
318122
318243
|
"lib/commands/agent.ts"() {
|
|
318123
|
-
"use strict";
|
|
318124
318244
|
init_types5();
|
|
318125
318245
|
init_registry();
|
|
318126
318246
|
init_errors();
|
|
@@ -323380,6 +323500,11 @@ function flowChild(node2, parent) {
|
|
|
323380
323500
|
if (cross2 === "HUG") style[crossProp] = null;
|
|
323381
323501
|
if ((parent.counterAxisAlignItems ?? "MIN") === "MIN") style["align-self"] = "flex-start";
|
|
323382
323502
|
}
|
|
323503
|
+
const ar = node2.aspectRatio;
|
|
323504
|
+
if (ar && ar > 0 && v !== "FILL") {
|
|
323505
|
+
style.height = null;
|
|
323506
|
+
style["aspect-ratio"] = String(Math.round(ar * 1e4) / 1e4);
|
|
323507
|
+
}
|
|
323383
323508
|
return { style };
|
|
323384
323509
|
}
|
|
323385
323510
|
function constrained(kind, pos, size6, parentSize, start2, end, sizeProp) {
|
|
@@ -323987,6 +324112,7 @@ var tree_exports = {};
|
|
|
323987
324112
|
__export(tree_exports, {
|
|
323988
324113
|
DEFAULT_NODE_CAP: () => DEFAULT_NODE_CAP,
|
|
323989
324114
|
EXPORT_NODE_CAP: () => EXPORT_NODE_CAP,
|
|
324115
|
+
breakpointPictures: () => breakpointPictures,
|
|
323990
324116
|
buildPlainTree: () => buildPlainTree,
|
|
323991
324117
|
buildWebTree: () => buildWebTree,
|
|
323992
324118
|
flatten: () => flatten2,
|
|
@@ -324332,7 +324458,7 @@ function buildPlainTree(doc2, nodeId2, opts = {}, start2, hooks = {}) {
|
|
|
324332
324458
|
}
|
|
324333
324459
|
} else for (const child of childrenOf(node2, nodesNow)) {
|
|
324334
324460
|
const built = build3(child, node2, kids3D, kidFold);
|
|
324335
|
-
if (built) web.children.push(built);
|
|
324461
|
+
if (built) web.children.push(...opts.target === "site" ? breakpointPictures(doc2, child, built) : [built]);
|
|
324336
324462
|
}
|
|
324337
324463
|
}
|
|
324338
324464
|
} finally {
|
|
@@ -324348,6 +324474,23 @@ function buildPlainTree(doc2, nodeId2, opts = {}, start2, hooks = {}) {
|
|
|
324348
324474
|
if (!root2) throw new Error("Node cap of 0");
|
|
324349
324475
|
return { root: root2, truncated, ...folds ? { rules: foldRules(folds) } : {}, ...tokens?.vars.length ? { tokens } : {} };
|
|
324350
324476
|
}
|
|
324477
|
+
function breakpointPictures(doc2, raw, built) {
|
|
324478
|
+
const r = raw.responsive;
|
|
324479
|
+
if (!built.asset || built.island || !r) return [built];
|
|
324480
|
+
const order2 = breakpointsOf(doc2).map((b) => b.id);
|
|
324481
|
+
const redrawn = order2.filter((b) => r[b]?.paths);
|
|
324482
|
+
if (!redrawn.length) return [built];
|
|
324483
|
+
const paths = JSON.stringify(raw.paths);
|
|
324484
|
+
const shown2 = [...redrawn].reverse().find((b) => JSON.stringify(r[b].paths) === paths) ?? null;
|
|
324485
|
+
const hide2 = (n) => ({ ...n, style: { ...n.style, display: "none" } });
|
|
324486
|
+
return [
|
|
324487
|
+
shown2 ? hide2(built) : built,
|
|
324488
|
+
...redrawn.map((b) => {
|
|
324489
|
+
const alt = { ...built, id: `${built.id}@${b}`, children: [], asset: { kind: built.asset.kind, reason: built.asset.reason, of: built.asset.of ?? built.id, breakpoint: b } };
|
|
324490
|
+
return b === shown2 ? alt : hide2(alt);
|
|
324491
|
+
})
|
|
324492
|
+
];
|
|
324493
|
+
}
|
|
324351
324494
|
function childLookup(doc2, id3) {
|
|
324352
324495
|
const at4 = id3.lastIndexOf("::");
|
|
324353
324496
|
const host = at4 > 0 ? id3.slice(0, at4) : "";
|
|
@@ -324364,6 +324507,7 @@ var init_tree = __esm({
|
|
|
324364
324507
|
"lib/io/web/tree.ts"() {
|
|
324365
324508
|
"use strict";
|
|
324366
324509
|
init_pixel_art();
|
|
324510
|
+
init_breakpoints();
|
|
324367
324511
|
init_instance_layout();
|
|
324368
324512
|
init_text_styles();
|
|
324369
324513
|
init_variables();
|
|
@@ -327984,7 +328128,7 @@ var init_package = __esm({
|
|
|
327984
328128
|
"packages/runtime/package.json"() {
|
|
327985
328129
|
package_default = {
|
|
327986
328130
|
name: "@popcraft/runtime",
|
|
327987
|
-
version: "0.
|
|
328131
|
+
version: "0.48.0",
|
|
327988
328132
|
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.",
|
|
327989
328133
|
license: "MIT",
|
|
327990
328134
|
homepage: "https://popcraft.app/docs/exporting/nextjs",
|
|
@@ -353226,7 +353370,7 @@ async function resolveWebAssets(tree, resolvers) {
|
|
|
353226
353370
|
const render2 = node2.asset.kind === "png" ? resolvers.renderPNG : resolvers.renderSVG;
|
|
353227
353371
|
if (!render2) return;
|
|
353228
353372
|
try {
|
|
353229
|
-
const out = await render2(node2.asset.of ?? node2.id, node2.asset.self ? { self: true } : void 0);
|
|
353373
|
+
const out = await render2(node2.asset.of ?? node2.id, node2.asset.self || node2.asset.breakpoint ? { ...node2.asset.self ? { self: true } : {}, ...node2.asset.breakpoint ? { breakpoint: node2.asset.breakpoint } : {} } : void 0);
|
|
353230
353374
|
if (!out) return;
|
|
353231
353375
|
if (node2.asset.kind === "png") node2.asset.pngDataUrl = out;
|
|
353232
353376
|
else node2.asset.svg = out;
|
|
@@ -353490,9 +353634,10 @@ __export(resolvers_exports, {
|
|
|
353490
353634
|
});
|
|
353491
353635
|
function rendererAssetResolvers(source3, scale = 2) {
|
|
353492
353636
|
const styles = source3.styles;
|
|
353493
|
-
const shownDoc = (id3) => {
|
|
353494
|
-
const
|
|
353495
|
-
|
|
353637
|
+
const shownDoc = (id3, breakpoint2) => {
|
|
353638
|
+
const at4 = breakpoint2 ? breakpointDocument(source3, breakpoint2) : source3;
|
|
353639
|
+
const n = at4.nodes[id3];
|
|
353640
|
+
return n && n.visible === false ? { ...at4, nodes: { ...at4.nodes, [id3]: { ...n, visible: true } } } : at4;
|
|
353496
353641
|
};
|
|
353497
353642
|
const alone = (doc2, id3) => {
|
|
353498
353643
|
const n = doc2.nodes[id3];
|
|
@@ -353501,10 +353646,10 @@ function rendererAssetResolvers(source3, scale = 2) {
|
|
|
353501
353646
|
return { doc: { ...doc2, nodes: { ...doc2.nodes, [id3]: node2 } }, node: node2 };
|
|
353502
353647
|
};
|
|
353503
353648
|
return {
|
|
353504
|
-
renderSVG: async (id3) => {
|
|
353649
|
+
renderSVG: async (id3, opts) => {
|
|
353505
353650
|
const renderer = getActiveRenderer();
|
|
353506
353651
|
if (!renderer) return null;
|
|
353507
|
-
const doc2 = shownDoc(id3);
|
|
353652
|
+
const doc2 = shownDoc(id3, opts?.breakpoint);
|
|
353508
353653
|
const node2 = nodeFor(doc2, id3);
|
|
353509
353654
|
const svg = node2 ? await exportNodeToSVG(renderer, node2, doc2, styles) : null;
|
|
353510
353655
|
if (svg) return svg;
|
|
@@ -353514,7 +353659,7 @@ function rendererAssetResolvers(source3, scale = 2) {
|
|
|
353514
353659
|
renderPNG: async (id3, opts) => {
|
|
353515
353660
|
const renderer = getActiveRenderer();
|
|
353516
353661
|
if (!renderer) return null;
|
|
353517
|
-
const doc2 = shownDoc(id3);
|
|
353662
|
+
const doc2 = shownDoc(id3, opts?.breakpoint);
|
|
353518
353663
|
if (opts?.self) {
|
|
353519
353664
|
const a = alone(doc2, id3);
|
|
353520
353665
|
const blob = a ? await exportNodeToBlob(renderer, a.node, { format: "PNG", scale, suffix: "" }, a.doc, styles) : null;
|
|
@@ -353533,6 +353678,7 @@ var init_resolvers = __esm({
|
|
|
353533
353678
|
"lib/io/web/resolvers.ts"() {
|
|
353534
353679
|
"use strict";
|
|
353535
353680
|
init_scene_graph();
|
|
353681
|
+
init_breakpoints();
|
|
353536
353682
|
init_renderer_registry();
|
|
353537
353683
|
init_export();
|
|
353538
353684
|
init_svg_export();
|
|
@@ -361206,7 +361352,6 @@ function publishSite(key5, files, opts = {}) {
|
|
|
361206
361352
|
var siteStatus, setSiteVersion, workspaceSites, deleteSite, renameSite;
|
|
361207
361353
|
var init_sites = __esm({
|
|
361208
361354
|
"lib/client/cloud/sites.ts"() {
|
|
361209
|
-
"use strict";
|
|
361210
361355
|
init_files();
|
|
361211
361356
|
init_upload2();
|
|
361212
361357
|
init_api4();
|
|
@@ -404051,7 +404196,14 @@ Set the timeline first, then add moves. Times are ms on the frame's timeline.
|
|
|
404051
404196
|
- On the phone \`webResponsive\` folds the nav's links and the layer named "Brand name" away, leaving the logo tile and
|
|
404052
404197
|
the button; to keep the name, call the brand text something else. Keep body text 14 px or more on the phone,
|
|
404053
404198
|
recompose the hero rather than cropping it, and keep every size under 8,192 px tall. Leave room in text boxes: a line that only just fits wraps differently
|
|
404054
|
-
in a browser
|
|
404199
|
+
in a browser.
|
|
404200
|
+
- A content picture on a page is \`k.contentImage(parent, url, width, { ratio, name, radius })\`: whole, at its own
|
|
404201
|
+
proportions (\`ratio\`, width over height, for a picture of your own), and its height follows the width its column
|
|
404202
|
+
gives it at every breakpoint and in the browser. Never crop a content picture to a fixed-height band: on a phone it
|
|
404203
|
+
loses its sides. Only decoration behind words may cover-crop (\`k.image\`), marked \`semantics: { hidden: true }\`.
|
|
404204
|
+
- What a breakpoint carries from a size: layout, size, visibility, type, and a drawing's scale, turn, offset and
|
|
404205
|
+
redrawn paths. Scale scenery down for the phone (\`scaleX\`/\`scaleY\` with \`anchorX: 0, anchorY: 0\`) rather than
|
|
404206
|
+
cutting it with a smaller frame. Ambient motion is not carried: it plays the desktop's keys at every width.`;
|
|
404055
404207
|
EDITING = `## Editing designs that already exist
|
|
404056
404208
|
|
|
404057
404209
|
Use \`run_script\` (from a terminal \`popcraft run <file> run_script --code @fix.js\`) to change many layers in one call.
|
|
@@ -413557,7 +413709,7 @@ init_resources();
|
|
|
413557
413709
|
init_desktop();
|
|
413558
413710
|
init_hypery();
|
|
413559
413711
|
import { createInterface } from "node:readline";
|
|
413560
|
-
var VERSION2 = "0.
|
|
413712
|
+
var VERSION2 = "0.48.0";
|
|
413561
413713
|
var HELP = `popcraft ${VERSION2} \u2014 the PopCraft command line
|
|
413562
413714
|
|
|
413563
413715
|
Files (headless, on .popcraft files):
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@popcraft/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.48.0",
|
|
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.
|
|
37
|
+
"@popcraft/kit": "0.48.0"
|
|
38
38
|
},
|
|
39
39
|
"scripts": {
|
|
40
40
|
"build": "node build.mjs",
|