@popcraft/cli 0.47.0 → 0.48.1

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.
Files changed (2) hide show
  1. package/dist/popcraft.mjs +238 -71
  2. 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.47.0"}`, ...opts.headers };
1199
+ const headers = { "user-agent": `popcraft-cli/${"0.48.1"}`, ...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",
@@ -33942,7 +33943,6 @@ var init_en2 = __esm({
33942
33943
  "homeTeam.viewListing": "View its marketplace listing",
33943
33944
  "homeTemplates.browseAll": "Browse all templates",
33944
33945
  "homeTemplates.communityBody": "Templates people made and shared. Tap one to start from a copy.",
33945
- "homeTemplates.couldNotLoad": "Templates couldn't load. Browse all templates to try again.",
33946
33946
  "homeTemplates.fromTheCommunity": "From the community",
33947
33947
  "homeTemplates.loading": "Loading templates\u2026",
33948
33948
  "homeTemplates.noneInThisGroup": "No templates in this group yet.",
@@ -34614,6 +34614,12 @@ var init_en2 = __esm({
34614
34614
  "objectActions.brushPartsOfThePicture": "Brush parts of the picture away \u2014 non-destructive, and you can paint them back",
34615
34615
  "objectActions.crop": "Crop",
34616
34616
  "objectActions.erase": "Erase",
34617
+ "offlineNotice.blankCanvas": "Start with a blank canvas",
34618
+ "offlineNotice.offlineBody": "This needs a connection. It loads by itself as soon as you\u2019re back online.",
34619
+ "offlineNotice.offlineTitle": "You\u2019re offline",
34620
+ "offlineNotice.retry": "Retry",
34621
+ "offlineNotice.unreachableBody": "Check your connection and try again.",
34622
+ "offlineNotice.unreachableTitle": "Couldn\u2019t reach PopCraft",
34617
34623
  "ownerPicker.loadingWorkspaces": "Loading workspaces",
34618
34624
  "ownerPicker.owner": "Owner: {name}",
34619
34625
  "pagePreset:a0": "A0",
@@ -38729,7 +38735,6 @@ var require_es = __commonJS({
38729
38735
  "homeTeam.viewListing": "Ver su listado en el marketplace",
38730
38736
  "homeTemplates.browseAll": "Explorar todas las plantillas",
38731
38737
  "homeTemplates.communityBody": "Plantillas creadas y compartidas por la gente. Toca una para empezar desde una copia.",
38732
- "homeTemplates.couldNotLoad": "No se pudieron cargar las plantillas. Explora todas las plantillas para intentarlo de nuevo.",
38733
38738
  "homeTemplates.fromTheCommunity": "De la comunidad",
38734
38739
  "homeTemplates.loading": "Cargando plantillas\u2026",
38735
38740
  "homeTemplates.noneInThisGroup": "A\xFAn no hay plantillas en este grupo.",
@@ -43505,7 +43510,6 @@ var require_fr = __commonJS({
43505
43510
  "homeTeam.viewListing": "Voir sa fiche sur la place de march\xE9",
43506
43511
  "homeTemplates.browseAll": "Parcourir tous les mod\xE8les",
43507
43512
  "homeTemplates.communityBody": "Mod\xE8les cr\xE9\xE9s et partag\xE9s par la communaut\xE9. Touchez-en un pour commencer \xE0 partir d\u2019une copie.",
43508
- "homeTemplates.couldNotLoad": "Impossible de charger les mod\xE8les. Parcourez tous les mod\xE8les pour r\xE9essayer.",
43509
43513
  "homeTemplates.fromTheCommunity": "De la communaut\xE9",
43510
43514
  "homeTemplates.loading": "Chargement des mod\xE8les\u2026",
43511
43515
  "homeTemplates.noneInThisGroup": "Aucun mod\xE8le dans ce groupe pour l\u2019instant.",
@@ -48281,7 +48285,6 @@ var require_de = __commonJS({
48281
48285
  "homeTeam.viewListing": "Marktplatz-Eintrag ansehen",
48282
48286
  "homeTemplates.browseAll": "Alle Vorlagen durchsuchen",
48283
48287
  "homeTemplates.communityBody": "Vorlagen, die andere erstellt und geteilt haben. Tippe auf eine, um mit einer Kopie zu beginnen.",
48284
- "homeTemplates.couldNotLoad": "Vorlagen konnten nicht geladen werden. Durchsuche alle Vorlagen, um es erneut zu versuchen.",
48285
48288
  "homeTemplates.fromTheCommunity": "Aus der Community",
48286
48289
  "homeTemplates.loading": "Vorlagen werden geladen\u2026",
48287
48290
  "homeTemplates.noneInThisGroup": "Noch keine Vorlagen in dieser Gruppe.",
@@ -53057,7 +53060,6 @@ var require_it = __commonJS({
53057
53060
  "homeTeam.viewListing": "Visualizza la sua inserzione nel marketplace",
53058
53061
  "homeTemplates.browseAll": "Sfoglia tutti i modelli",
53059
53062
  "homeTemplates.communityBody": "Modelli creati e condivisi dalla community. Toccane uno per iniziare da una copia.",
53060
- "homeTemplates.couldNotLoad": "Impossibile caricare i modelli. Sfoglia tutti i modelli per riprovare.",
53061
53063
  "homeTemplates.fromTheCommunity": "Dalla community",
53062
53064
  "homeTemplates.loading": "Caricamento modelli\u2026",
53063
53065
  "homeTemplates.noneInThisGroup": "Nessun modello in questo gruppo per ora.",
@@ -57833,7 +57835,6 @@ var require_pt_BR = __commonJS({
57833
57835
  "homeTeam.viewListing": "Ver sua listagem no marketplace",
57834
57836
  "homeTemplates.browseAll": "Procurar todos os modelos",
57835
57837
  "homeTemplates.communityBody": "Modelos criados e compartilhados por pessoas. Toque em um para come\xE7ar a partir de uma c\xF3pia.",
57836
- "homeTemplates.couldNotLoad": "N\xE3o foi poss\xEDvel carregar os modelos. Procure todos os modelos para tentar novamente.",
57837
57838
  "homeTemplates.fromTheCommunity": "Da comunidade",
57838
57839
  "homeTemplates.loading": "Carregando modelos\u2026",
57839
57840
  "homeTemplates.noneInThisGroup": "Nenhum modelo neste grupo ainda.",
@@ -62609,7 +62610,6 @@ var require_ja = __commonJS({
62609
62610
  "homeTeam.viewListing": "\u30DE\u30FC\u30B1\u30C3\u30C8\u30D7\u30EC\u30A4\u30B9\u306E\u63B2\u8F09\u60C5\u5831\u3092\u8868\u793A",
62610
62611
  "homeTemplates.browseAll": "\u3059\u3079\u3066\u306E\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8\u3092\u53C2\u7167",
62611
62612
  "homeTemplates.communityBody": "\u4EBA\u3005\u304C\u4F5C\u6210\u30FB\u5171\u6709\u3057\u305F\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8\u3002\u30BF\u30C3\u30D7\u3057\u3066\u30B3\u30D4\u30FC\u304B\u3089\u958B\u59CB\u3057\u307E\u3059\u3002",
62612
- "homeTemplates.couldNotLoad": "\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8\u3092\u8AAD\u307F\u8FBC\u3081\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u3059\u3079\u3066\u306E\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8\u3092\u53C2\u7167\u3057\u3066\u518D\u8A66\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
62613
62613
  "homeTemplates.fromTheCommunity": "\u30B3\u30DF\u30E5\u30CB\u30C6\u30A3\u304B\u3089",
62614
62614
  "homeTemplates.loading": "\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8\u3092\u8AAD\u307F\u8FBC\u307F\u4E2D\u2026",
62615
62615
  "homeTemplates.noneInThisGroup": "\u3053\u306E\u30B0\u30EB\u30FC\u30D7\u306B\u306F\u307E\u3060\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8\u304C\u3042\u308A\u307E\u305B\u3093\u3002",
@@ -67385,7 +67385,6 @@ var require_ko = __commonJS({
67385
67385
  "homeTeam.viewListing": "\uB9C8\uCF13\uD50C\uB808\uC774\uC2A4 \uBAA9\uB85D \uBCF4\uAE30",
67386
67386
  "homeTemplates.browseAll": "\uBAA8\uB4E0 \uD15C\uD50C\uB9BF \uCC3E\uC544\uBCF4\uAE30",
67387
67387
  "homeTemplates.communityBody": "\uC0AC\uB78C\uB4E4\uC774 \uB9CC\uB4E4\uACE0 \uACF5\uC720\uD55C \uD15C\uD50C\uB9BF\uC785\uB2C8\uB2E4. \uD0ED\uD558\uC5EC \uC0AC\uBCF8\uC73C\uB85C \uC2DC\uC791\uD558\uC138\uC694.",
67388
- "homeTemplates.couldNotLoad": "\uD15C\uD50C\uB9BF\uC744 \uB85C\uB4DC\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. \uBAA8\uB4E0 \uD15C\uD50C\uB9BF\uC744 \uCC3E\uC544 \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC138\uC694.",
67389
67388
  "homeTemplates.fromTheCommunity": "\uCEE4\uBBA4\uB2C8\uD2F0\uC5D0\uC11C",
67390
67389
  "homeTemplates.loading": "\uD15C\uD50C\uB9BF \uB85C\uB4DC \uC911\u2026",
67391
67390
  "homeTemplates.noneInThisGroup": "\uC774 \uADF8\uB8F9\uC5D0\uB294 \uC544\uC9C1 \uD15C\uD50C\uB9BF\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.",
@@ -72161,7 +72160,6 @@ var require_zh_CN = __commonJS({
72161
72160
  "homeTeam.viewListing": "\u67E5\u770B\u5176\u5E02\u573A\u5217\u8868",
72162
72161
  "homeTemplates.browseAll": "\u6D4F\u89C8\u6240\u6709\u6A21\u677F",
72163
72162
  "homeTemplates.communityBody": "\u5927\u5BB6\u5236\u4F5C\u5E76\u5206\u4EAB\u7684\u6A21\u677F\u3002\u8F7B\u70B9\u4E00\u4E2A\u5373\u53EF\u4ECE\u526F\u672C\u5F00\u59CB\u3002",
72164
- "homeTemplates.couldNotLoad": "\u6A21\u677F\u65E0\u6CD5\u52A0\u8F7D\u3002\u8BF7\u6D4F\u89C8\u6240\u6709\u6A21\u677F\u91CD\u8BD5\u3002",
72165
72163
  "homeTemplates.fromTheCommunity": "\u6765\u81EA\u793E\u533A",
72166
72164
  "homeTemplates.loading": "\u6B63\u5728\u52A0\u8F7D\u6A21\u677F\u2026",
72167
72165
  "homeTemplates.noneInThisGroup": "\u6B64\u7EC4\u4E2D\u6682\u65E0\u6A21\u677F\u3002",
@@ -76937,7 +76935,6 @@ var require_zh_TW = __commonJS({
76937
76935
  "homeTeam.viewListing": "\u67E5\u770B\u5176\u5E02\u96C6\u4E0A\u67B6\u8CC7\u8A0A",
76938
76936
  "homeTemplates.browseAll": "\u700F\u89BD\u6240\u6709\u7BC4\u672C",
76939
76937
  "homeTemplates.communityBody": "\u4EBA\u5011\u88FD\u4F5C\u4E26\u5206\u4EAB\u7684\u7BC4\u672C\u3002\u8F15\u9EDE\u4E00\u500B\u5373\u53EF\u5F9E\u526F\u672C\u958B\u59CB\u3002",
76940
- "homeTemplates.couldNotLoad": "\u7BC4\u672C\u7121\u6CD5\u8F09\u5165\u3002\u700F\u89BD\u6240\u6709\u7BC4\u672C\u4EE5\u91CD\u8A66\u3002",
76941
76938
  "homeTemplates.fromTheCommunity": "\u4F86\u81EA\u793E\u7FA4",
76942
76939
  "homeTemplates.loading": "\u6B63\u5728\u8F09\u5165\u7BC4\u672C\u2026",
76943
76940
  "homeTemplates.noneInThisGroup": "\u6B64\u7FA4\u7D44\u4E2D\u5C1A\u7121\u7BC4\u672C\u3002",
@@ -81713,7 +81710,6 @@ var require_ru = __commonJS({
81713
81710
  "homeTeam.viewListing": "\u041F\u0440\u043E\u0441\u043C\u043E\u0442\u0440\u0435\u0442\u044C \u043E\u0431\u044A\u044F\u0432\u043B\u0435\u043D\u0438\u0435 \u043D\u0430 \u043C\u0430\u0440\u043A\u0435\u0442\u043F\u043B\u0435\u0439\u0441\u0435",
81714
81711
  "homeTemplates.browseAll": "\u041F\u0440\u043E\u0441\u043C\u043E\u0442\u0440\u0435\u0442\u044C \u0432\u0441\u0435 \u0448\u0430\u0431\u043B\u043E\u043D\u044B",
81715
81712
  "homeTemplates.communityBody": "\u0428\u0430\u0431\u043B\u043E\u043D\u044B, \u0441\u043E\u0437\u0434\u0430\u043D\u043D\u044B\u0435 \u0438 \u043E\u043F\u0443\u0431\u043B\u0438\u043A\u043E\u0432\u0430\u043D\u043D\u044B\u0435 \u0434\u0440\u0443\u0433\u0438\u043C\u0438 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F\u043C\u0438. \u041D\u0430\u0436\u043C\u0438\u0442\u0435 \u043D\u0430 \u043E\u0434\u0438\u043D, \u0447\u0442\u043E\u0431\u044B \u043D\u0430\u0447\u0430\u0442\u044C \u0441 \u043A\u043E\u043F\u0438\u0438.",
81716
- "homeTemplates.couldNotLoad": "\u041D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0448\u0430\u0431\u043B\u043E\u043D\u044B. \u041F\u0440\u043E\u0441\u043C\u043E\u0442\u0440\u0438\u0442\u0435 \u0432\u0441\u0435 \u0448\u0430\u0431\u043B\u043E\u043D\u044B, \u0447\u0442\u043E\u0431\u044B \u043F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u044C \u043F\u043E\u043F\u044B\u0442\u043A\u0443.",
81717
81713
  "homeTemplates.fromTheCommunity": "\u041E\u0442 \u0441\u043E\u043E\u0431\u0449\u0435\u0441\u0442\u0432\u0430",
81718
81714
  "homeTemplates.loading": "\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430 \u0448\u0430\u0431\u043B\u043E\u043D\u043E\u0432\u2026",
81719
81715
  "homeTemplates.noneInThisGroup": "\u0412 \u044D\u0442\u043E\u0439 \u0433\u0440\u0443\u043F\u043F\u0435 \u043F\u043E\u043A\u0430 \u043D\u0435\u0442 \u0448\u0430\u0431\u043B\u043E\u043D\u043E\u0432.",
@@ -86489,7 +86485,6 @@ var require_ar = __commonJS({
86489
86485
  "homeTeam.viewListing": "\u0639\u0631\u0636 \u0625\u062F\u0631\u0627\u062C\u0647 \u0641\u064A \u0627\u0644\u0645\u062A\u062C\u0631",
86490
86486
  "homeTemplates.browseAll": "\u062A\u0635\u0641\u062D \u062C\u0645\u064A\u0639 \u0627\u0644\u0642\u0648\u0627\u0644\u0628",
86491
86487
  "homeTemplates.communityBody": "\u0642\u0648\u0627\u0644\u0628 \u0623\u0646\u0634\u0623\u0647\u0627 \u0648\u0634\u0627\u0631\u0643\u0647\u0627 \u0627\u0644\u0622\u062E\u0631\u0648\u0646. \u0627\u0646\u0642\u0631 \u0639\u0644\u0649 \u0623\u062D\u062F\u0647\u0627 \u0644\u0644\u0628\u062F\u0621 \u0645\u0646 \u0646\u0633\u062E\u0629.",
86492
- "homeTemplates.couldNotLoad": "\u062A\u0639\u0630\u0631 \u062A\u062D\u0645\u064A\u0644 \u0627\u0644\u0642\u0648\u0627\u0644\u0628. \u062A\u0635\u0641\u062D \u062C\u0645\u064A\u0639 \u0627\u0644\u0642\u0648\u0627\u0644\u0628 \u0644\u0644\u0645\u062D\u0627\u0648\u0644\u0629 \u0645\u0631\u0629 \u0623\u062E\u0631\u0649.",
86493
86488
  "homeTemplates.fromTheCommunity": "\u0645\u0646 \u0627\u0644\u0645\u062C\u062A\u0645\u0639",
86494
86489
  "homeTemplates.loading": "\u062C\u0627\u0631\u064D \u062A\u062D\u0645\u064A\u0644 \u0627\u0644\u0642\u0648\u0627\u0644\u0628\u2026",
86495
86490
  "homeTemplates.noneInThisGroup": "\u0644\u0627 \u062A\u0648\u062C\u062F \u0642\u0648\u0627\u0644\u0628 \u0641\u064A \u0647\u0630\u0647 \u0627\u0644\u0645\u062C\u0645\u0648\u0639\u0629 \u0628\u0639\u062F.",
@@ -91265,7 +91260,6 @@ var require_hi = __commonJS({
91265
91260
  "homeTeam.viewListing": "\u0907\u0938\u0915\u0940 \u092E\u093E\u0930\u094D\u0915\u0947\u091F\u092A\u094D\u0932\u0947\u0938 \u0932\u093F\u0938\u094D\u091F\u093F\u0902\u0917 \u0926\u0947\u0916\u0947\u0902",
91266
91261
  "homeTemplates.browseAll": "\u0938\u092D\u0940 \u091F\u0947\u092E\u094D\u092A\u094D\u0932\u0947\u091F \u092C\u094D\u0930\u093E\u0909\u091C\u093C \u0915\u0930\u0947\u0902",
91267
91262
  "homeTemplates.communityBody": "\u0932\u094B\u0917\u094B\u0902 \u0926\u094D\u0935\u093E\u0930\u093E \u092C\u0928\u093E\u090F \u0914\u0930 \u0938\u093E\u091D\u093E \u0915\u093F\u090F \u0917\u090F \u091F\u0947\u092E\u094D\u092A\u0932\u0947\u091F\u0964 \u0915\u0949\u092A\u0940 \u0938\u0947 \u0936\u0941\u0930\u0942 \u0915\u0930\u0928\u0947 \u0915\u0947 \u0932\u093F\u090F \u0915\u093F\u0938\u0940 \u090F\u0915 \u092A\u0930 \u091F\u0948\u092A \u0915\u0930\u0947\u0902\u0964",
91268
- "homeTemplates.couldNotLoad": "\u091F\u0947\u092E\u094D\u092A\u094D\u0932\u0947\u091F \u0932\u094B\u0921 \u0928\u0939\u0940\u0902 \u0939\u094B \u0938\u0915\u0947\u0964 \u092B\u093F\u0930 \u0938\u0947 \u092A\u094D\u0930\u092F\u093E\u0938 \u0915\u0930\u0928\u0947 \u0915\u0947 \u0932\u093F\u090F \u0938\u092D\u0940 \u091F\u0947\u092E\u094D\u092A\u094D\u0932\u0947\u091F \u092C\u094D\u0930\u093E\u0909\u091C\u093C \u0915\u0930\u0947\u0902\u0964",
91269
91263
  "homeTemplates.fromTheCommunity": "\u0938\u092E\u0941\u0926\u093E\u092F \u0938\u0947",
91270
91264
  "homeTemplates.loading": "\u091F\u0947\u092E\u094D\u092A\u094D\u0932\u0947\u091F \u0932\u094B\u0921 \u0939\u094B \u0930\u0939\u0947 \u0939\u0948\u0902\u2026",
91271
91265
  "homeTemplates.noneInThisGroup": "\u0907\u0938 \u0938\u092E\u0942\u0939 \u092E\u0947\u0902 \u0905\u092D\u0940 \u0915\u094B\u0908 \u091F\u0947\u092E\u094D\u092A\u094D\u0932\u0947\u091F \u0928\u0939\u0940\u0902 \u0939\u0948\u0964",
@@ -97957,6 +97951,11 @@ function applyAutoLayout(doc2) {
97957
97951
  } else {
97958
97952
  let height = node2.height;
97959
97953
  let width = node2.width;
97954
+ const ar = node2.aspectRatio;
97955
+ if (ar && ar > 0 && node2.layoutSizingVertical !== "FILL" && Math.abs(width / ar - height) > 0.01) {
97956
+ height = Math.round(width / ar * 1e3) / 1e3;
97957
+ cloneNode(nodeId2).height = height;
97958
+ }
97960
97959
  if (node2.type === "INSTANCE") {
97961
97960
  const h = instanceContentHeight(newNodes, nodeId2);
97962
97961
  if (h !== null && Math.abs(h - height) > 0.5) {
@@ -98085,6 +98084,8 @@ function applyAutoLayout(doc2) {
98085
98084
  const r = Math.floor(index2 / actualCols);
98086
98085
  if (child.layoutSizingHorizontal === "FILL") child.width = clampedWidth(colW[c2], child);
98087
98086
  if (child.layoutSizingVertical === "FILL") child.height = clampedHeight(rowH[r], child);
98087
+ keepAspect(child);
98088
+ fitWipe(child, newNodes, cloneNode);
98088
98089
  const cellX = colX[c2];
98089
98090
  const cellY = rowY[r];
98090
98091
  child.x = cellX;
@@ -98123,6 +98124,8 @@ function applyAutoLayout(doc2) {
98123
98124
  if (child.layoutSizingVertical === "FILL") child.height = clampedHeight(fillPrimarySize, child);
98124
98125
  if (child.layoutSizingHorizontal === "FILL") child.width = clampedWidth(Math.max(0, frame3.width - paddingX), child);
98125
98126
  }
98127
+ keepAspect(child);
98128
+ fitWipe(child, newNodes, cloneNode);
98126
98129
  });
98127
98130
  if (wraps(frame3)) {
98128
98131
  const lines2 = wrapLines(frame3, childIds, (id3) => ({ intrinsicWidth: newNodes[id3].width, intrinsicHeight: newNodes[id3].height }));
@@ -98191,7 +98194,12 @@ function applyAutoLayout(doc2) {
98191
98194
  });
98192
98195
  }
98193
98196
  }
98194
- autoLayoutRoots.forEach((root2) => {
98197
+ let aspect = false;
98198
+ for (const id3 in newNodes) if (newNodes[id3].aspectRatio) {
98199
+ aspect = true;
98200
+ break;
98201
+ }
98202
+ for (let pass = 0; pass < (aspect ? 2 : 1); pass++) autoLayoutRoots.forEach((root2) => {
98195
98203
  measureNode(root2.id);
98196
98204
  layoutNode(root2.id);
98197
98205
  });
@@ -98204,6 +98212,21 @@ function applyAutoLayout(doc2) {
98204
98212
  }
98205
98213
  return { ...doc2, nodes: newNodes };
98206
98214
  }
98215
+ function keepAspect(n) {
98216
+ if (n.aspectRatio > 0 && n.layoutSizingVertical !== "FILL") n.height = Math.round(n.width / n.aspectRatio * 1e3) / 1e3;
98217
+ }
98218
+ function fitWipe(group2, nodes, clone2) {
98219
+ if (group2.type !== "GROUP" || !group2.isMaskGroup || !group2.childIds.some((id3) => nodes[id3]?.isMask && nodes[id3]?.name === "Wipe mask")) return;
98220
+ const w = group2.layoutSizingHorizontal === "FILL", h = group2.layoutSizingVertical === "FILL" || group2.aspectRatio > 0;
98221
+ if (!w && !h) return;
98222
+ for (const id3 of group2.childIds) {
98223
+ const c2 = nodes[id3];
98224
+ if (!c2 || (!w || c2.width === group2.width) && (!h || c2.height === group2.height)) continue;
98225
+ const n = clone2(id3);
98226
+ if (w) n.width = group2.width;
98227
+ if (h) n.height = group2.height;
98228
+ }
98229
+ }
98207
98230
  function wraps(frame3) {
98208
98231
  if (frame3.layoutWrap !== "WRAP" || frame3.layoutMode === "GRID") return false;
98209
98232
  return frame3.layoutMode === "HORIZONTAL" ? frame3.layoutSizingHorizontal !== "HUG" : frame3.layoutSizingVertical !== "HUG";
@@ -246764,6 +246787,45 @@ function lineWidth(line, family, weight, fontSize, italic, shaping) {
246764
246787
  }
246765
246788
  return units * fontSize;
246766
246789
  }
246790
+ function unitAdvances(line, family, weight, fontSize, italic, shaping) {
246791
+ const out = new Array(line.length).fill(0);
246792
+ if (!line) return out;
246793
+ const share = (start2, len3, em) => {
246794
+ const n = Math.max(1, len3);
246795
+ for (let k2 = 0; k2 < n && start2 + k2 < line.length; k2++) out[start2 + k2] += em * fontSize / n;
246796
+ };
246797
+ const place4 = (glyphs, upem, offset, notdef) => {
246798
+ for (const g of glyphs) {
246799
+ if (notdef && g.gid === 0) {
246800
+ if (g.clusterLength === 0) continue;
246801
+ const text = line.slice(offset + g.clusterStart, offset + g.clusterStart + g.clusterLength);
246802
+ share(offset + g.clusterStart, g.clusterLength, fallbackEm(text, family, weight, italic));
246803
+ continue;
246804
+ }
246805
+ share(offset + g.clusterStart, g.clusterLength, g.xAdvance / upem);
246806
+ }
246807
+ };
246808
+ const shaped = shapeRun(line, family, italic, weight, shaping?.features, shaping?.variations);
246809
+ if (shaped) {
246810
+ place4(shaped.glyphs, shaped.unitsPerEm, 0, true);
246811
+ return out;
246812
+ }
246813
+ const fb = shapeFallback(line, family, italic, weight, shaping?.features);
246814
+ if (fb === "loading") {
246815
+ let i2 = 0;
246816
+ for (const ch of line) {
246817
+ share(i2, ch.length, fallbackEm(ch, family, weight, italic));
246818
+ i2 += ch.length;
246819
+ }
246820
+ return out;
246821
+ }
246822
+ for (const item of fb.items) place4(item.shaped.glyphs, item.shaped.unitsPerEm, item.start, false);
246823
+ for (const i2 of fb.missing) {
246824
+ const c2 = line.charCodeAt(i2);
246825
+ if (!(c2 >= 56320 && c2 <= 57343 && i2 > 0)) out[i2] += 0.5 * fontSize;
246826
+ }
246827
+ return out;
246828
+ }
246767
246829
  function fallbackEm(text, family, weight, italic, strict = false) {
246768
246830
  let em = 0;
246769
246831
  for (const ch of text) {
@@ -246795,24 +246857,35 @@ function casedText(text, textCase) {
246795
246857
  function measureAutoWidth(t3) {
246796
246858
  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
246859
  }
246798
- function estimateTextHeight(characters, width, family, weight, size6, lineHeight, wraps2 = true, letterSpacing = 0) {
246799
- const lh2 = lineHeight === "AUTO" ? size6 * 1.25 : lineHeight;
246800
- const measure4 = (t3, fallbackChars) => measureTextWidth(t3, family, weight, size6, void 0, letterSpacing) || (size6 * 0.55 + letterSpacing) * fallbackChars;
246860
+ function estimateTextHeight(characters, width, family, weight, size6, lineHeight, wraps2 = true, letterSpacing = 0, setting = {}) {
246861
+ const lh2 = lineHeight === "AUTO" ? size6 * 1.2 : lineHeight;
246862
+ const italic = setting.fontStyle === "italic";
246801
246863
  let lines2 = 0;
246802
246864
  for (const para of characters.split("\n")) {
246803
- let cur = 0, n = 1;
246804
- if (wraps2) for (const word of para.split(" ")) {
246805
- const w = measure4(word, word.length);
246806
- const space = cur > 0 ? measure4(" ", 1) : 0;
246807
- if (cur > 0 && cur + space + w > width) {
246808
- n++;
246809
- cur = w;
246810
- } else cur += space + w;
246865
+ lines2++;
246866
+ if (!wraps2 || !para) continue;
246867
+ const adv = unitAdvances(para, family, weight, size6, italic, setting.shaping);
246868
+ let start2 = 0, w = 0, lastSpace = -1;
246869
+ for (let i2 = 0; i2 < para.length; i2++) {
246870
+ const a = adv[i2] + letterSpacing;
246871
+ const space = para[i2] === " ";
246872
+ if (!space && w + a > width && lastSpace !== -1 && start2 < lastSpace) {
246873
+ lines2++;
246874
+ start2 = lastSpace + 1;
246875
+ w = 0;
246876
+ for (let j = start2; j <= i2; j++) w += adv[j] + letterSpacing;
246877
+ lastSpace = -1;
246878
+ } else {
246879
+ if (space) lastSpace = i2;
246880
+ w += a;
246881
+ }
246811
246882
  }
246812
- lines2 += n;
246813
246883
  }
246814
246884
  return Math.max(lh2, lines2 * lh2);
246815
246885
  }
246886
+ function textSetting(t3) {
246887
+ return { fontStyle: t3.fontStyle, shaping: { features: t3.fontFeatures, variations: t3.fontVariations } };
246888
+ }
246816
246889
  var init_measure = __esm({
246817
246890
  "lib/engine/text/measure.ts"() {
246818
246891
  "use strict";
@@ -246833,7 +246906,7 @@ function autoTextBounds(node2, styles) {
246833
246906
  const chars = casedText(resolved.characters || "", resolved.textCase);
246834
246907
  const family = resolved.fontFamily || "Inter", weight = resolved.fontWeight || 400, size6 = resolved.fontSize || 16;
246835
246908
  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);
246909
+ const estimate2 = estimateTextHeight(chars, width, family, weight, size6, resolved.lineHeight ?? "AUTO", !hugs2, resolved.letterSpacing || 0, textSetting(resolved));
246837
246910
  return { width, height: hugs2 ? estimate2 : Math.max(node2.height, estimate2) };
246838
246911
  }
246839
246912
  var init_text_bounds = __esm({
@@ -247990,6 +248063,7 @@ function resyncText(doc2, ids2) {
247990
248063
  var isVirtualId;
247991
248064
  var init_invariants2 = __esm({
247992
248065
  "lib/document/invariants.ts"() {
248066
+ "use strict";
247993
248067
  init_auto_layout();
247994
248068
  init_scene_graph();
247995
248069
  init_text_bounds();
@@ -259138,7 +259212,11 @@ function ensureWipeMask(nodes, id3, hostFrameId) {
259138
259212
  childIds: [maskId, id3],
259139
259213
  blendMode: "NORMAL",
259140
259214
  isMaskGroup: true,
259141
- ...n.layoutPositioning ? { layoutPositioning: n.layoutPositioning } : {}
259215
+ ...n.layoutPositioning ? { layoutPositioning: n.layoutPositioning } : {},
259216
+ // A picture that keeps its proportions (a page's content picture) is wiped in its place in the layout: the group
259217
+ // fills and keeps proportions as the picture did, and the layout sizes what it holds to it (lib/document/auto-layout.ts
259218
+ // `fitWipe`), so a phone scales it rather than keeping the desktop's width.
259219
+ ...n.aspectRatio ? Object.fromEntries(["layoutSizingHorizontal", "layoutSizingVertical", "aspectRatio"].filter((k2) => n[k2] !== void 0).map((k2) => [k2, n[k2]])) : {}
259142
259220
  };
259143
259221
  const moved3 = { ...n, parentId: gid, x: 0, y: 0, motion: shiftPositionKeys(n.motion, -n.x, -n.y) };
259144
259222
  if (!moved3.motion) delete moved3.motion;
@@ -261041,11 +261119,32 @@ function breakpointDocument(doc2, id3) {
261041
261119
  const width = isScreen(doc2, n) && over2?.width === void 0 ? { width: bp.previewWidth } : null;
261042
261120
  if (over2 || width) nodes[nid] = { ...n, ...over2, ...width };
261043
261121
  }
261044
- const view2 = applyAutoLayout({ ...doc2, nodes });
261122
+ const view2 = rewrapped(doc2, applyAutoLayout({ ...doc2, nodes }));
261045
261123
  const forDoc = viewMemo.get(doc2) ?? viewMemo.set(doc2, /* @__PURE__ */ new Map()).get(doc2);
261046
261124
  forDoc.set(id3, view2);
261047
261125
  return view2;
261048
261126
  }
261127
+ function rewrapped(doc2, view2) {
261128
+ for (let pass = 0; pass < 3; pass++) {
261129
+ let nodes = null;
261130
+ for (const id3 in view2.nodes) {
261131
+ const n = view2.nodes[id3], was = doc2.nodes[id3];
261132
+ if (n.type !== "TEXT" || !n.visible || !was) continue;
261133
+ const t3 = n;
261134
+ if (t3.textAutoResize === "NONE") continue;
261135
+ if (Math.abs(t3.width - was.width) < 0.5 && t3.textStyleId === was.textStyleId && t3.fontSize === was.fontSize && t3.textAutoResize === was.textAutoResize) continue;
261136
+ const m = measureTextLayout(resolveTextNodeStyles(t3, doc2.styles ?? {}));
261137
+ if (!m) continue;
261138
+ const width = t3.textAutoResize === "WIDTH_AND_HEIGHT" ? m.width : t3.width;
261139
+ if (Math.abs(m.height - t3.height) < 0.5 && Math.abs(width - t3.width) < 0.5) continue;
261140
+ nodes ??= { ...view2.nodes };
261141
+ nodes[id3] = { ...t3, width, height: m.height };
261142
+ }
261143
+ if (!nodes) break;
261144
+ view2 = applyAutoLayout({ ...view2, nodes });
261145
+ }
261146
+ return view2;
261147
+ }
261049
261148
  function withOverrides(node2, id3, overrides2) {
261050
261149
  const next2 = { ...node2.responsive };
261051
261150
  if (Object.keys(overrides2).length) next2[id3] = overrides2;
@@ -261081,8 +261180,9 @@ function laidOut(nodes, n, key5) {
261081
261180
  const inFlow3 = !!parent && parent.layoutMode !== void 0 && parent.layoutMode !== "NONE" && s.layoutPositioning !== "ABSOLUTE";
261082
261181
  const lays = own2.layoutMode !== void 0 && own2.layoutMode !== "NONE";
261083
261182
  if (key5 === "x" || key5 === "y") return inFlow3;
261084
- if (key5 === "width") return s.layoutSizingHorizontal === "FILL" || s.layoutSizingHorizontal === "HUG" && (lays || n.type === "TEXT");
261085
- if (key5 === "height") return s.layoutSizingVertical === "FILL" || s.layoutSizingVertical === "HUG" && (lays || n.type === "TEXT") || n.type === "TEXT" && n.textAutoResize !== "NONE";
261183
+ const fills = (sizing3) => sizing3 === "FILL" && s.layoutPositioning !== "ABSOLUTE";
261184
+ if (key5 === "width") return fills(s.layoutSizingHorizontal) || s.layoutSizingHorizontal === "HUG" && (lays || n.type === "TEXT");
261185
+ if (key5 === "height") return fills(s.layoutSizingVertical) || s.layoutSizingVertical === "HUG" && (lays || n.type === "TEXT") || n.type === "TEXT" && n.textAutoResize !== "NONE";
261086
261186
  return false;
261087
261187
  }
261088
261188
  function breakpointResult(rest, baked, edited, id3) {
@@ -261123,7 +261223,9 @@ function foldVariant(doc2, masterId, variantId, id3) {
261123
261223
  const restyled = variant.textStyleId !== master.textStyleId;
261124
261224
  for (const k2 of RESPONSIVE_PROPS) {
261125
261225
  if (isRoot && (k2 === "x" || k2 === "y" || k2 === "width")) continue;
261126
- const value3 = variant[k2];
261226
+ const set4 = variant[k2];
261227
+ const inherited = k2 in UNSET && (master[k2] !== void 0 || overridesAt(master, doc2, id3)?.[k2] !== void 0);
261228
+ const value3 = set4 ?? (inherited ? UNSET[k2] : void 0);
261127
261229
  if (value3 === void 0 || laidOut(doc2.nodes, variant, k2)) continue;
261128
261230
  if ((k2 === "fontSize" || k2 === "lineHeight") && restyled) continue;
261129
261231
  props[k2] = value3;
@@ -261149,11 +261251,13 @@ function setBreakpoints(doc2, list2) {
261149
261251
  }
261150
261252
  return nodes ? { ...next2, nodes } : next2;
261151
261253
  }
261152
- var DEFAULT_BREAKPOINTS, RESPONSIVE_PROPS, RESPONSIVE, isBaseBreakpoint, same2, ownOverrides, isScreen, viewMemo;
261254
+ var DEFAULT_BREAKPOINTS, RESPONSIVE_PROPS, RESPONSIVE, isBaseBreakpoint, UNSET, same2, ownOverrides, isScreen, viewMemo;
261153
261255
  var init_breakpoints = __esm({
261154
261256
  "lib/document/breakpoints.ts"() {
261155
261257
  "use strict";
261156
261258
  init_auto_layout();
261259
+ init_instance_layout();
261260
+ init_text_styles();
261157
261261
  DEFAULT_BREAKPOINTS = [
261158
261262
  { id: "desktop", name: "Desktop", maxWidth: null, previewWidth: 1280 },
261159
261263
  { id: "tablet", name: "Tablet", maxWidth: 1024, previewWidth: 834 },
@@ -261183,10 +261287,24 @@ var init_breakpoints = __esm({
261183
261287
  "fontSize",
261184
261288
  "lineHeight",
261185
261289
  "textAlign",
261186
- "textStyleId"
261290
+ "textStyleId",
261291
+ "scaleX",
261292
+ "scaleY",
261293
+ "anchorX",
261294
+ "anchorY",
261295
+ "rotation",
261296
+ "cornerRadius",
261297
+ "textAutoResize",
261298
+ "paths",
261299
+ "translateX",
261300
+ "translateY",
261301
+ "z",
261302
+ "rotateX",
261303
+ "rotateY"
261187
261304
  ];
261188
261305
  RESPONSIVE = new Set(RESPONSIVE_PROPS);
261189
261306
  isBaseBreakpoint = (doc2, id3) => !id3 || breakpointsOf(doc2)[0].id === id3 || !breakpointsOf(doc2).some((b) => b.id === id3);
261307
+ UNSET = { scaleX: 1, scaleY: 1, anchorX: 0.5, anchorY: 0.5, rotation: 0, translateX: 0, translateY: 0, z: 0, rotateX: 0, rotateY: 0 };
261190
261308
  same2 = (a, b) => a === b || typeof a === "object" && typeof b === "object" && JSON.stringify(a) === JSON.stringify(b);
261191
261309
  ownOverrides = (node2, id3) => Object.keys(node2?.responsive?.[id3] ?? {});
261192
261310
  isScreen = (doc2, n) => n.type === "FRAME" && doc2.nodes[n.parentId ?? ""]?.type === "PAGE";
@@ -262373,6 +262491,29 @@ var init_plugin_store = __esm({
262373
262491
  }
262374
262492
  });
262375
262493
 
262494
+ // lib/client/network.ts
262495
+ function isOnline() {
262496
+ return typeof navigator === "undefined" || navigator.onLine !== false;
262497
+ }
262498
+ function networkSignal(signal, timeoutMs = NETWORK_TIMEOUT_MS) {
262499
+ if (!isOnline()) throw new OfflineError();
262500
+ const deadline = AbortSignal.timeout(timeoutMs);
262501
+ return signal ? AbortSignal.any([signal, deadline]) : deadline;
262502
+ }
262503
+ var import_react3, NETWORK_TIMEOUT_MS, OfflineError;
262504
+ var init_network = __esm({
262505
+ "lib/client/network.ts"() {
262506
+ import_react3 = __toESM(require_react());
262507
+ NETWORK_TIMEOUT_MS = 8e3;
262508
+ OfflineError = class extends Error {
262509
+ constructor() {
262510
+ super("You are offline");
262511
+ this.name = "OfflineError";
262512
+ }
262513
+ };
262514
+ }
262515
+ });
262516
+
262376
262517
  // lib/client/cloud/plan-limit.ts
262377
262518
  var plan_limit_exports = {};
262378
262519
  __export(plan_limit_exports, {
@@ -262457,7 +262598,6 @@ function formatLimit(key5, max3) {
262457
262598
  var formatBytes;
262458
262599
  var init_limits2 = __esm({
262459
262600
  "lib/billing/limits.ts"() {
262460
- "use strict";
262461
262601
  init_format();
262462
262602
  init_plans();
262463
262603
  formatBytes = formatFileSize;
@@ -262692,7 +262832,8 @@ function api(path, init = {}) {
262692
262832
  inFlight.set(path, value3);
262693
262833
  return value3;
262694
262834
  }
262695
- async function request(path, init) {
262835
+ async function request(path, { timeoutMs, ...init }) {
262836
+ if (timeoutMs !== void 0) init = { ...init, signal: networkSignal(init.signal, timeoutMs) };
262696
262837
  const headers = new Headers(init.headers);
262697
262838
  const token = await accessToken();
262698
262839
  if (token) headers.set("authorization", `Bearer ${token}`);
@@ -262720,6 +262861,7 @@ var ApiError, inFlight, fileUrl, meInFlight, provisioned, ME_TTL_MS, cloudApi;
262720
262861
  var init_api4 = __esm({
262721
262862
  "lib/client/cloud/api.ts"() {
262722
262863
  "use strict";
262864
+ init_network();
262723
262865
  init_session();
262724
262866
  init_plan_limit();
262725
262867
  init_purchases();
@@ -273214,10 +273356,10 @@ function loadEntitlements(workspaceId, opts = {}) {
273214
273356
  });
273215
273357
  return value3;
273216
273358
  }
273217
- var import_react3, TTL_MS, cache6, lastResolved, cachedLimits;
273359
+ var import_react4, TTL_MS, cache6, lastResolved, cachedLimits;
273218
273360
  var init_entitlements = __esm({
273219
273361
  "lib/client/cloud/entitlements.ts"() {
273220
- import_react3 = __toESM(require_react());
273362
+ import_react4 = __toESM(require_react());
273221
273363
  init_api4();
273222
273364
  init_config2();
273223
273365
  init_limits2();
@@ -310611,8 +310753,8 @@ async function render(frame3, doc2) {
310611
310753
  }
310612
310754
  function usePageThumbnail(frame3, doc2) {
310613
310755
  const cached3 = cache8.get(frame3);
310614
- const [url4, setUrl] = (0, import_react4.useState)(cached3?.url ?? null);
310615
- (0, import_react4.useEffect)(() => {
310756
+ const [url4, setUrl] = (0, import_react5.useState)(cached3?.url ?? null);
310757
+ (0, import_react5.useEffect)(() => {
310616
310758
  let cancelled = false;
310617
310759
  const hit = cache8.get(frame3);
310618
310760
  if (hit && hit.doc === doc2) {
@@ -310642,11 +310784,11 @@ function usePageThumbnail(frame3, doc2) {
310642
310784
  }, [frame3, doc2]);
310643
310785
  return url4;
310644
310786
  }
310645
- var import_react4, THUMB_PX, SETTLE_MS, cache8;
310787
+ var import_react5, THUMB_PX, SETTLE_MS, cache8;
310646
310788
  var init_page_thumbnails = __esm({
310647
310789
  "lib/client/page-thumbnails.ts"() {
310648
310790
  "use strict";
310649
- import_react4 = __toESM(require_react());
310791
+ import_react5 = __toESM(require_react());
310650
310792
  init_renderer_registry();
310651
310793
  init_jpeg();
310652
310794
  init_thumbnail();
@@ -310744,7 +310886,7 @@ async function deleteCloudTemplate(id3) {
310744
310886
  useCloudTemplates.setState((s) => ({ available: s.available.filter((x2) => x2.id !== id3) }));
310745
310887
  }
310746
310888
  async function fetchCloudTemplate(id3) {
310747
- const { template: template2, payload } = await api(`/api/templates/${encodeURIComponent(id3)}`, { cache: "no-store", signal: AbortSignal.timeout(3e4) });
310889
+ const { template: template2, payload } = await api(`/api/templates/${encodeURIComponent(id3)}`, { cache: "no-store", timeoutMs: 3e4 });
310748
310890
  return { meta: template2, payload };
310749
310891
  }
310750
310892
  async function searchTemplates(o = {}) {
@@ -310758,7 +310900,7 @@ async function searchTemplates(o = {}) {
310758
310900
  if (o.sort) sp.set("sort", o.sort);
310759
310901
  if (o.cursor) sp.set("cursor", o.cursor);
310760
310902
  if (o.limit) sp.set("limit", String(o.limit));
310761
- return api(`/api/templates?${sp}`);
310903
+ return api(`/api/templates?${sp}`, { timeoutMs: NETWORK_TIMEOUT_MS });
310762
310904
  }
310763
310905
  async function setTemplateOfficial(id3, official) {
310764
310906
  const { template: template2 } = await api(`/api/templates/${encodeURIComponent(id3)}/official`, { method: official ? "POST" : "DELETE" });
@@ -310772,6 +310914,7 @@ var init_templates = __esm({
310772
310914
  init_esm();
310773
310915
  init_idb();
310774
310916
  init_api4();
310917
+ init_network();
310775
310918
  init_session();
310776
310919
  init_upload();
310777
310920
  init_card();
@@ -311661,7 +311804,6 @@ async function dispatchShaped(key5, options) {
311661
311804
  var onViolation;
311662
311805
  var init_dispatch = __esm({
311663
311806
  "lib/commands/dispatch.ts"() {
311664
- "use strict";
311665
311807
  init_errors();
311666
311808
  init_registry();
311667
311809
  init_confirm();
@@ -311721,7 +311863,7 @@ var init_text_measurer = __esm({
311721
311863
  const width = node2.textAutoResize === "WIDTH_AND_HEIGHT" ? Math.max(1, Math.ceil(measureAutoWidth(node2))) : node2.width;
311722
311864
  return {
311723
311865
  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))
311866
+ 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
311867
  };
311726
311868
  };
311727
311869
  }
@@ -312061,7 +312203,6 @@ function creditLine(c2) {
312061
312203
  var MAX_PHOTO_PAGE, MAX_PHOTO_QUERY, UUID, isPhotoId, photoImagePath;
312062
312204
  var init_stock = __esm({
312063
312205
  "lib/photos/stock.ts"() {
312064
- "use strict";
312065
312206
  MAX_PHOTO_PAGE = 12;
312066
312207
  MAX_PHOTO_QUERY = 200;
312067
312208
  UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
@@ -312723,7 +312864,6 @@ function applyTextPath(layout2, path, tp, rebase = true) {
312723
312864
  var defaultCircleRadius, ownsPath, mapPoint;
312724
312865
  var init_text_path = __esm({
312725
312866
  "lib/engine/text/text-path.ts"() {
312726
- "use strict";
312727
312867
  init_scene_graph();
312728
312868
  init_transform();
312729
312869
  init_shape_to_path();
@@ -312841,7 +312981,6 @@ function areaBounds(rings) {
312841
312981
  }
312842
312982
  var init_text_area = __esm({
312843
312983
  "lib/engine/text/text-area.ts"() {
312844
- "use strict";
312845
312984
  }
312846
312985
  });
312847
312986
 
@@ -313504,7 +313643,7 @@ function layoutTextUncached(node2, atlas, cameraZoom = 1) {
313504
313643
  }
313505
313644
  }
313506
313645
  if (hyphenated) {
313507
- } else if (currentIndent + lineWidth2 + advance > maxWidth2 && lastSpaceIndex !== -1 && lineStartIndex < lastSpaceIndex) {
313646
+ } else if (!isSpace2 && currentIndent + lineWidth2 + advance > maxWidth2 && lastSpaceIndex !== -1 && lineStartIndex < lastSpaceIndex) {
313508
313647
  let wrappedLineHeight = 0;
313509
313648
  for (let j = lineStartIndex; j < lastSpaceIndex; j++) {
313510
313649
  const lh3 = resolvedStyles[j].lineHeight === "AUTO" ? resolvedStyles[j].fontSize * 1.2 : resolvedStyles[j].lineHeight;
@@ -317186,7 +317325,6 @@ async function exportSettingFile(renderer, node2, setting, doc2, styles) {
317186
317325
  var MIME, DEFAULT_EXPORT, exportSettingsOf;
317187
317326
  var init_export = __esm({
317188
317327
  "lib/io/export.ts"() {
317189
- "use strict";
317190
317328
  init_download();
317191
317329
  init_scene_graph();
317192
317330
  init_codecs();
@@ -317278,6 +317416,7 @@ async function selectionReferenceImages(doc2, selection, opts = {}) {
317278
317416
  var FIT_QUALITIES, FIT_SCALES, blobToDataUrl;
317279
317417
  var init_reference_images = __esm({
317280
317418
  "lib/ai/reference-images.ts"() {
317419
+ "use strict";
317281
317420
  init_export();
317282
317421
  init_selection_bounds();
317283
317422
  init_renderer_registry();
@@ -323380,6 +323519,11 @@ function flowChild(node2, parent) {
323380
323519
  if (cross2 === "HUG") style[crossProp] = null;
323381
323520
  if ((parent.counterAxisAlignItems ?? "MIN") === "MIN") style["align-self"] = "flex-start";
323382
323521
  }
323522
+ const ar = node2.aspectRatio;
323523
+ if (ar && ar > 0 && v !== "FILL") {
323524
+ style.height = null;
323525
+ style["aspect-ratio"] = String(Math.round(ar * 1e4) / 1e4);
323526
+ }
323383
323527
  return { style };
323384
323528
  }
323385
323529
  function constrained(kind, pos, size6, parentSize, start2, end, sizeProp) {
@@ -323987,6 +324131,7 @@ var tree_exports = {};
323987
324131
  __export(tree_exports, {
323988
324132
  DEFAULT_NODE_CAP: () => DEFAULT_NODE_CAP,
323989
324133
  EXPORT_NODE_CAP: () => EXPORT_NODE_CAP,
324134
+ breakpointPictures: () => breakpointPictures,
323990
324135
  buildPlainTree: () => buildPlainTree,
323991
324136
  buildWebTree: () => buildWebTree,
323992
324137
  flatten: () => flatten2,
@@ -324332,7 +324477,7 @@ function buildPlainTree(doc2, nodeId2, opts = {}, start2, hooks = {}) {
324332
324477
  }
324333
324478
  } else for (const child of childrenOf(node2, nodesNow)) {
324334
324479
  const built = build3(child, node2, kids3D, kidFold);
324335
- if (built) web.children.push(built);
324480
+ if (built) web.children.push(...opts.target === "site" ? breakpointPictures(doc2, child, built) : [built]);
324336
324481
  }
324337
324482
  }
324338
324483
  } finally {
@@ -324348,6 +324493,23 @@ function buildPlainTree(doc2, nodeId2, opts = {}, start2, hooks = {}) {
324348
324493
  if (!root2) throw new Error("Node cap of 0");
324349
324494
  return { root: root2, truncated, ...folds ? { rules: foldRules(folds) } : {}, ...tokens?.vars.length ? { tokens } : {} };
324350
324495
  }
324496
+ function breakpointPictures(doc2, raw, built) {
324497
+ const r = raw.responsive;
324498
+ if (!built.asset || built.island || !r) return [built];
324499
+ const order2 = breakpointsOf(doc2).map((b) => b.id);
324500
+ const redrawn = order2.filter((b) => r[b]?.paths);
324501
+ if (!redrawn.length) return [built];
324502
+ const paths = JSON.stringify(raw.paths);
324503
+ const shown2 = [...redrawn].reverse().find((b) => JSON.stringify(r[b].paths) === paths) ?? null;
324504
+ const hide2 = (n) => ({ ...n, style: { ...n.style, display: "none" } });
324505
+ return [
324506
+ shown2 ? hide2(built) : built,
324507
+ ...redrawn.map((b) => {
324508
+ 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 } };
324509
+ return b === shown2 ? alt : hide2(alt);
324510
+ })
324511
+ ];
324512
+ }
324351
324513
  function childLookup(doc2, id3) {
324352
324514
  const at4 = id3.lastIndexOf("::");
324353
324515
  const host = at4 > 0 ? id3.slice(0, at4) : "";
@@ -324364,6 +324526,7 @@ var init_tree = __esm({
324364
324526
  "lib/io/web/tree.ts"() {
324365
324527
  "use strict";
324366
324528
  init_pixel_art();
324529
+ init_breakpoints();
324367
324530
  init_instance_layout();
324368
324531
  init_text_styles();
324369
324532
  init_variables();
@@ -327984,7 +328147,7 @@ var init_package = __esm({
327984
328147
  "packages/runtime/package.json"() {
327985
328148
  package_default = {
327986
328149
  name: "@popcraft/runtime",
327987
- version: "0.47.0",
328150
+ version: "0.48.1",
327988
328151
  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
328152
  license: "MIT",
327990
328153
  homepage: "https://popcraft.app/docs/exporting/nextjs",
@@ -352650,7 +352813,6 @@ function exportsOf(source3) {
352650
352813
  var CODE_LIMITS, packageOf;
352651
352814
  var init_source2 = __esm({
352652
352815
  "lib/code/source.ts"() {
352653
- "use strict";
352654
352816
  CODE_LIMITS = { modules: 100, sourceLength: 2e5, packages: 12 };
352655
352817
  packageOf = (spec) => spec.split("/").slice(0, spec.startsWith("@") ? 2 : 1).join("/");
352656
352818
  }
@@ -352693,7 +352855,6 @@ function compileModule(module2) {
352693
352855
  var import_sucrase, BUILT_IN, memo4;
352694
352856
  var init_compile2 = __esm({
352695
352857
  "lib/code/compile.ts"() {
352696
- "use strict";
352697
352858
  import_sucrase = __toESM(require_dist2());
352698
352859
  init_source2();
352699
352860
  init_source2();
@@ -353226,7 +353387,7 @@ async function resolveWebAssets(tree, resolvers) {
353226
353387
  const render2 = node2.asset.kind === "png" ? resolvers.renderPNG : resolvers.renderSVG;
353227
353388
  if (!render2) return;
353228
353389
  try {
353229
- const out = await render2(node2.asset.of ?? node2.id, node2.asset.self ? { self: true } : void 0);
353390
+ 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
353391
  if (!out) return;
353231
353392
  if (node2.asset.kind === "png") node2.asset.pngDataUrl = out;
353232
353393
  else node2.asset.svg = out;
@@ -353490,9 +353651,10 @@ __export(resolvers_exports, {
353490
353651
  });
353491
353652
  function rendererAssetResolvers(source3, scale = 2) {
353492
353653
  const styles = source3.styles;
353493
- const shownDoc = (id3) => {
353494
- const n = source3.nodes[id3];
353495
- return n && n.visible === false ? { ...source3, nodes: { ...source3.nodes, [id3]: { ...n, visible: true } } } : source3;
353654
+ const shownDoc = (id3, breakpoint2) => {
353655
+ const at4 = breakpoint2 ? breakpointDocument(source3, breakpoint2) : source3;
353656
+ const n = at4.nodes[id3];
353657
+ return n && n.visible === false ? { ...at4, nodes: { ...at4.nodes, [id3]: { ...n, visible: true } } } : at4;
353496
353658
  };
353497
353659
  const alone = (doc2, id3) => {
353498
353660
  const n = doc2.nodes[id3];
@@ -353501,10 +353663,10 @@ function rendererAssetResolvers(source3, scale = 2) {
353501
353663
  return { doc: { ...doc2, nodes: { ...doc2.nodes, [id3]: node2 } }, node: node2 };
353502
353664
  };
353503
353665
  return {
353504
- renderSVG: async (id3) => {
353666
+ renderSVG: async (id3, opts) => {
353505
353667
  const renderer = getActiveRenderer();
353506
353668
  if (!renderer) return null;
353507
- const doc2 = shownDoc(id3);
353669
+ const doc2 = shownDoc(id3, opts?.breakpoint);
353508
353670
  const node2 = nodeFor(doc2, id3);
353509
353671
  const svg = node2 ? await exportNodeToSVG(renderer, node2, doc2, styles) : null;
353510
353672
  if (svg) return svg;
@@ -353514,7 +353676,7 @@ function rendererAssetResolvers(source3, scale = 2) {
353514
353676
  renderPNG: async (id3, opts) => {
353515
353677
  const renderer = getActiveRenderer();
353516
353678
  if (!renderer) return null;
353517
- const doc2 = shownDoc(id3);
353679
+ const doc2 = shownDoc(id3, opts?.breakpoint);
353518
353680
  if (opts?.self) {
353519
353681
  const a = alone(doc2, id3);
353520
353682
  const blob = a ? await exportNodeToBlob(renderer, a.node, { format: "PNG", scale, suffix: "" }, a.doc, styles) : null;
@@ -353533,6 +353695,7 @@ var init_resolvers = __esm({
353533
353695
  "lib/io/web/resolvers.ts"() {
353534
353696
  "use strict";
353535
353697
  init_scene_graph();
353698
+ init_breakpoints();
353536
353699
  init_renderer_registry();
353537
353700
  init_export();
353538
353701
  init_svg_export();
@@ -361206,7 +361369,6 @@ function publishSite(key5, files, opts = {}) {
361206
361369
  var siteStatus, setSiteVersion, workspaceSites, deleteSite, renameSite;
361207
361370
  var init_sites = __esm({
361208
361371
  "lib/client/cloud/sites.ts"() {
361209
- "use strict";
361210
361372
  init_files();
361211
361373
  init_upload2();
361212
361374
  init_api4();
@@ -361734,7 +361896,6 @@ var init_delete_current_file = __esm({
361734
361896
  var storeOpsSeam;
361735
361897
  var init_seams = __esm({
361736
361898
  "lib/commands/seams.ts"() {
361737
- "use strict";
361738
361899
  storeOpsSeam = (st) => ({
361739
361900
  booleanOperation: (op4) => st().booleanOperation(op4),
361740
361901
  flatten: () => st().flattenSelection(),
@@ -362718,15 +362879,15 @@ function usePickableThemes() {
362718
362879
  const userThemes = useThemeStore((s) => s.userThemes);
362719
362880
  const pluginThemes = useThemeStore((s) => s.pluginThemes);
362720
362881
  const localThemes = useThemeStore((s) => s.localThemes);
362721
- return (0, import_react9.useMemo)(() => pickableThemes({ userThemes, pluginThemes, localThemes }), [userThemes, pluginThemes, localThemes]);
362882
+ return (0, import_react10.useMemo)(() => pickableThemes({ userThemes, pluginThemes, localThemes }), [userThemes, pluginThemes, localThemes]);
362722
362883
  }
362723
- var import_react9, IDB_KEY, useThemeStore, cssString2, defaultAccent, effectiveAccent;
362884
+ var import_react10, IDB_KEY, useThemeStore, cssString2, defaultAccent, effectiveAccent;
362724
362885
  var init_theme_store = __esm({
362725
362886
  "lib/theme/theme-store.ts"() {
362726
362887
  init_contrast();
362727
362888
  init_idb();
362728
362889
  init_esm();
362729
- import_react9 = __toESM(require_react());
362890
+ import_react10 = __toESM(require_react());
362730
362891
  init_boot2();
362731
362892
  init_builtin();
362732
362893
  init_resolve();
@@ -404051,7 +404212,14 @@ Set the timeline first, then add moves. Times are ms on the frame's timeline.
404051
404212
  - On the phone \`webResponsive\` folds the nav's links and the layer named "Brand name" away, leaving the logo tile and
404052
404213
  the button; to keep the name, call the brand text something else. Keep body text 14 px or more on the phone,
404053
404214
  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.`;
404215
+ in a browser.
404216
+ - A content picture on a page is \`k.contentImage(parent, url, width, { ratio, name, radius })\`: whole, at its own
404217
+ proportions (\`ratio\`, width over height, for a picture of your own), and its height follows the width its column
404218
+ gives it at every breakpoint and in the browser. Never crop a content picture to a fixed-height band: on a phone it
404219
+ loses its sides. Only decoration behind words may cover-crop (\`k.image\`), marked \`semantics: { hidden: true }\`.
404220
+ - What a breakpoint carries from a size: layout, size, visibility, type, and a drawing's scale, turn, offset and
404221
+ redrawn paths. Scale scenery down for the phone (\`scaleX\`/\`scaleY\` with \`anchorX: 0, anchorY: 0\`) rather than
404222
+ cutting it with a smaller frame. Ambient motion is not carried: it plays the desktop's keys at every width.`;
404055
404223
  EDITING = `## Editing designs that already exist
404056
404224
 
404057
404225
  Use \`run_script\` (from a terminal \`popcraft run <file> run_script --code @fix.js\`) to change many layers in one call.
@@ -405953,7 +406121,6 @@ function registerBuiltinCommands() {
405953
406121
  var builtinCommands, uiOnlyCommands;
405954
406122
  var init_builtin4 = __esm({
405955
406123
  "lib/commands/builtin.ts"() {
405956
- "use strict";
405957
406124
  init_registry();
405958
406125
  init_node();
405959
406126
  init_node();
@@ -413557,7 +413724,7 @@ init_resources();
413557
413724
  init_desktop();
413558
413725
  init_hypery();
413559
413726
  import { createInterface } from "node:readline";
413560
- var VERSION2 = "0.47.0";
413727
+ var VERSION2 = "0.48.1";
413561
413728
  var HELP = `popcraft ${VERSION2} \u2014 the PopCraft command line
413562
413729
 
413563
413730
  Files (headless, on .popcraft files):
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@popcraft/cli",
3
- "version": "0.47.0",
3
+ "version": "0.48.1",
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.47.0"
37
+ "@popcraft/kit": "0.48.1"
38
38
  },
39
39
  "scripts": {
40
40
  "build": "node build.mjs",