@popcraft/kit 0.53.17 → 0.53.18

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 (81) hide show
  1. package/dist/chunks/{agent-76MOJF7H.js → agent-QSCYOPEH.js} +1 -1
  2. package/dist/chunks/{builtin-O5D2Q6RV.js → builtin-5P5A2IMY.js} +4 -4
  3. package/dist/chunks/{buy-credits-2RI5ALP3.js → buy-credits-LK6QXRXO.js} +2 -2
  4. package/dist/chunks/{check-template-5FJPJLKN.js → check-template-SWWOPCV6.js} +3 -3
  5. package/dist/chunks/{chunk-GZZNTUHF.js → chunk-2O3AJLC7.js} +5 -5
  6. package/dist/chunks/{chunk-MUOTQRR5.js → chunk-35ZHGX7R.js} +3 -3
  7. package/dist/chunks/{chunk-YZYQTXAK.js → chunk-56ZMLITS.js} +4 -4
  8. package/dist/chunks/{chunk-64TRA3OH.js → chunk-735IMMB6.js} +4 -4
  9. package/dist/chunks/{chunk-ZIOF5AO6.js → chunk-7G7UOKM4.js} +1 -1
  10. package/dist/chunks/{chunk-MEEB2X3B.js → chunk-7HICNIH2.js} +54 -54
  11. package/dist/chunks/{chunk-4UOE2QLJ.js → chunk-7PRWYB7R.js} +4 -4
  12. package/dist/chunks/{chunk-NH42V7UK.js → chunk-7R77JLIP.js} +1 -1
  13. package/dist/chunks/{chunk-E4P2HVUD.js → chunk-AN22TGNL.js} +3 -1
  14. package/dist/chunks/{chunk-B4FB4B2M.js → chunk-ASMDKFSL.js} +1 -1
  15. package/dist/chunks/{chunk-AMQ2XV6E.js → chunk-C4JKLCPX.js} +10 -10
  16. package/dist/chunks/{chunk-SAUZ2HYM.js → chunk-E6LFTCYF.js} +4 -4
  17. package/dist/chunks/{chunk-QJU5LRJX.js → chunk-ETC4DTCD.js} +2 -2
  18. package/dist/chunks/{chunk-ROIDWBDQ.js → chunk-F4AFFSFA.js} +4 -4
  19. package/dist/chunks/{chunk-N6T6XKGC.js → chunk-GZWJRQRF.js} +1 -1
  20. package/dist/chunks/{chunk-LVENLTN6.js → chunk-HC2BCDFS.js} +4 -4
  21. package/dist/chunks/{chunk-ZEERADTI.js → chunk-I5VBP754.js} +12 -12
  22. package/dist/chunks/{chunk-IIPH3CZZ.js → chunk-IY5UZMTO.js} +251 -2
  23. package/dist/chunks/{chunk-U6OKU7J4.js → chunk-L5MSOOYG.js} +2 -2
  24. package/dist/chunks/{chunk-IAL55FGC.js → chunk-LC62KWV5.js} +2 -2
  25. package/dist/chunks/{chunk-SELEMFEP.js → chunk-LPGPKUME.js} +1 -1
  26. package/dist/chunks/{chunk-YLNK64NW.js → chunk-MGLGBL5N.js} +12 -12
  27. package/dist/chunks/{chunk-UXNXHMBD.js → chunk-NK4G5HDO.js} +5 -7
  28. package/dist/chunks/{chunk-VRGEEHBR.js → chunk-OK3DQPII.js} +269 -50
  29. package/dist/chunks/{chunk-QS4AT3DM.js → chunk-RPZJC2IG.js} +2 -4
  30. package/dist/chunks/{chunk-NAXSGXBD.js → chunk-VWL5XI7L.js} +11 -11
  31. package/dist/chunks/{chunk-XKUI2K2V.js → chunk-X4JKF2JG.js} +214 -1
  32. package/dist/chunks/{chunk-K63NQAOB.js → chunk-XE6NJFI2.js} +89 -89
  33. package/dist/chunks/{client-3EX4LVI6.js → client-3JR3D6HI.js} +3 -3
  34. package/dist/chunks/{client-RIPJA5PK.js → client-7ABQN2CO.js} +1 -1
  35. package/dist/chunks/{client-N525NCFB.js → client-LHZIJH23.js} +2 -2
  36. package/dist/chunks/{client-actions-232DIA3G.js → client-actions-VNMC4A7Z.js} +13 -14
  37. package/dist/chunks/{dangerous-2CPJMLP6.js → dangerous-VGWX2YEI.js} +4 -4
  38. package/dist/chunks/{delete-current-file-IVQD2M3K.js → delete-current-file-5IZOBWY2.js} +9 -10
  39. package/dist/chunks/{editor-seams-AFXFNM6K.js → editor-seams-4M7R4HNW.js} +18 -20
  40. package/dist/chunks/{editor-store-ZFR2ZHNM.js → editor-store-L4V3QA4A.js} +5 -5
  41. package/dist/chunks/{export-FWVSW5AN.js → export-FZA6A6I6.js} +1 -1
  42. package/dist/chunks/{export-watermark-KT25FYVD.js → export-watermark-3FQ7QOYR.js} +9 -10
  43. package/dist/chunks/{eyedropper-W6X2VHUB.js → eyedropper-P3ZONVHS.js} +7 -11
  44. package/dist/chunks/{generate-media-Y3NYLLSS.js → generate-media-SSWL4Y2L.js} +4 -4
  45. package/dist/chunks/{host-PKGEIJZF.js → host-VSSIPMLW.js} +14 -17
  46. package/dist/chunks/{integrations-4NFCLH3S.js → integrations-OQV4PCCS.js} +1 -1
  47. package/dist/chunks/{libraries-565L4UXX.js → libraries-CWODJKJI.js} +9 -10
  48. package/dist/chunks/{live-X3AP4MHF.js → live-DQITX7DB.js} +5 -5
  49. package/dist/chunks/{lottie-AGAHYTZE.js → lottie-ZKR6H64U.js} +3 -4
  50. package/dist/chunks/{media-tool-HVMNAVAE.js → media-tool-3IFICUR3.js} +12 -126
  51. package/dist/chunks/{new-file-Z7EJFO2J.js → new-file-GYD6TJYO.js} +7 -7
  52. package/dist/chunks/{pdf-X3ZB6QKO.js → pdf-RPD6QHMP.js} +5 -7
  53. package/dist/chunks/{player-check-ZGWLAHXY.js → player-check-CZVWUJXW.js} +3 -4
  54. package/dist/chunks/{plugin-OLV3V7ZN.js → plugin-V2XZNMZE.js} +3 -3
  55. package/dist/chunks/{plugin-import-SM3NLQ5A.js → plugin-import-UFRJVWX3.js} +23 -26
  56. package/dist/chunks/{pptx-OI7DTHPN.js → pptx-QZMA6SRM.js} +3 -4
  57. package/dist/chunks/{presence-TL24PA2T.js → presence-GGLTIRS2.js} +6 -6
  58. package/dist/chunks/{project-TS27R5XO.js → project-XENIE5UL.js} +3 -3
  59. package/dist/chunks/{publish-site-34NCZ274.js → publish-site-HBMHT6ZH.js} +10 -11
  60. package/dist/chunks/{publish-store-V27NWG4I.js → publish-store-PFXW7OCQ.js} +5 -5
  61. package/dist/chunks/{raster-actions-PGNW6BX6.js → raster-actions-ZGFZYTAH.js} +7 -11
  62. package/dist/chunks/{reference-images-36D6WIRI.js → reference-images-RAJE3NRE.js} +2 -2
  63. package/dist/chunks/{resolvers-V6SR7XRN.js → resolvers-J3DRJJ7P.js} +5 -6
  64. package/dist/chunks/{runner-Q6HI2WVB.js → runner-KSX7DGFW.js} +25 -27
  65. package/dist/chunks/{store-SIAVD2I6.js → store-4GUNFV7U.js} +14 -15
  66. package/dist/chunks/{storefront-prepare-6WYLPH6E.js → storefront-prepare-S6A5FZXC.js} +1 -1
  67. package/dist/chunks/{svg-export-QTVHP7B2.js → svg-export-J23NHZWC.js} +4 -5
  68. package/dist/chunks/{sync-PQCW3ZLW.js → sync-K2VRUB23.js} +9 -10
  69. package/dist/chunks/{tabs-HTDE6XGQ.js → tabs-A6SMBMFX.js} +12 -12
  70. package/dist/chunks/{team-H4DYU4NF.js → team-T3SVBBAO.js} +1 -1
  71. package/dist/chunks/{team-client-DW5CMJ4L.js → team-client-S3GCAISX.js} +1 -1
  72. package/dist/chunks/{theme-store-FAYEXX7K.js → theme-store-CBS2LI4H.js} +2 -3
  73. package/dist/chunks/{tools-HBJ2I7YP.js → tools-JRQSLBJK.js} +2 -2
  74. package/dist/chunks/{ui-commands-NRTJFHI6.js → ui-commands-ECGJ3AYH.js} +20 -22
  75. package/dist/chunks/{versions-22FL7N6P.js → versions-MP3FT4IV.js} +9 -10
  76. package/dist/index.js +1 -1
  77. package/package.json +1 -1
  78. package/dist/chunks/chunk-C3QJHVOH.js +0 -269
  79. package/dist/chunks/chunk-I5REOOP7.js +0 -225
  80. package/dist/chunks/chunk-P4LE4WLR.js +0 -25
  81. package/dist/chunks/chunk-ZBANBY2Q.js +0 -27
@@ -8,7 +8,7 @@ import {
8
8
  needsSelection,
9
9
  pageGo,
10
10
  selectionIsPicture
11
- } from "./chunk-MEEB2X3B.js";
11
+ } from "./chunk-7HICNIH2.js";
12
12
  import {
13
13
  external_exports
14
14
  } from "./chunk-UDDWBCFE.js";
@@ -31,7 +31,7 @@ var none = external_exports.object({});
31
31
  var emit = (name, detail) => {
32
32
  if (typeof window !== "undefined") window.dispatchEvent(new CustomEvent(name, { detail }));
33
33
  };
34
- var store = () => import("./editor-store-ZFR2ZHNM.js").then((m) => m.useEditorStore.getState());
34
+ var store = () => import("./editor-store-L4V3QA4A.js").then((m) => m.useEditorStore.getState());
35
35
  var MODE_IDS = MODE_LIST.map((m) => m.id);
36
36
  var MODE_ALIASES = { JAM: "POPCORN", DEV: "VIEW" };
37
37
  var modeSet = defineCommand({
@@ -161,13 +161,13 @@ var dialogOpen = defineCommand({
161
161
  (await import("./plugin-store-M7EIBRYQ.js")).usePluginStore.getState().setManagerOpen(true);
162
162
  break;
163
163
  case "theme-editor":
164
- (await import("./theme-store-FAYEXX7K.js")).useThemeStore.getState().setEditorOpen(true);
164
+ (await import("./theme-store-CBS2LI4H.js")).useThemeStore.getState().setEditorOpen(true);
165
165
  break;
166
166
  case "plan":
167
167
  (await import("./plan-limit-NQZVPJSA.js")).openPlanDialog();
168
168
  break;
169
169
  case "credits":
170
- await (await import("./buy-credits-2RI5ALP3.js")).buyAiCredits();
170
+ await (await import("./buy-credits-LK6QXRXO.js")).buyAiCredits();
171
171
  break;
172
172
  case "tokens":
173
173
  emit("popcraft-open-tokens");
@@ -213,7 +213,7 @@ var aiOpen = defineCommand({
213
213
  ] } },
214
214
  run: async ({ dialog, skillId }) => {
215
215
  if (dialog) (await import("./client-store-4J5MJDAW.js")).openAiDialog(dialog);
216
- else (await import("./store-SIAVD2I6.js")).openAgentPanel({ skillId: skillId ?? null });
216
+ else (await import("./store-4GUNFV7U.js")).openAgentPanel({ skillId: skillId ?? null });
217
217
  return { summary: dialog ? `Opened AI ${dialog}` : "Opened the agent" };
218
218
  }
219
219
  });
@@ -226,7 +226,7 @@ var agentContinue = defineCommand({
226
226
  params: external_exports.object({}),
227
227
  expose: { ui: { label: "AI: Continue the agent\u2019s last turn", keywords: ["ai", "agent", "continue", "resume", "retry", "keep going"] } },
228
228
  run: async () => {
229
- const resumed = await (await import("./runner-Q6HI2WVB.js")).continueTurn();
229
+ const resumed = await (await import("./runner-KSX7DGFW.js")).continueTurn();
230
230
  return { summary: resumed ? "Continued the agent" : "Nothing to continue" };
231
231
  }
232
232
  });
@@ -305,11 +305,11 @@ var toolPlace = defineCommand({
305
305
  run: async ({ what }) => {
306
306
  if (what === "media") {
307
307
  const s = await store();
308
- const { placeMediaFromPicker } = await import("./media-tool-HVMNAVAE.js");
308
+ const { placeMediaFromPicker } = await import("./media-tool-3IFICUR3.js");
309
309
  await placeMediaFromPicker({ kind: "point", x: s.camera.x, y: s.camera.y });
310
310
  return { summary: "Placing media" };
311
311
  }
312
- const { beginEyedrop } = await import("./eyedropper-W6X2VHUB.js");
312
+ const { beginEyedrop } = await import("./eyedropper-P3ZONVHS.js");
313
313
  void beginEyedrop();
314
314
  return { summary: "Pick a color" };
315
315
  }
@@ -327,7 +327,7 @@ var nodeRasterize = defineCommand({
327
327
  keywords: ["rasterize", "raster", "flatten", "pixels", "paint layer", "erase", "bitmap"]
328
328
  } },
329
329
  run: async () => {
330
- const { flattenSelectionToPaintLayer } = await import("./raster-actions-PGNW6BX6.js");
330
+ const { flattenSelectionToPaintLayer } = await import("./raster-actions-ZGFZYTAH.js");
331
331
  await flattenSelectionToPaintLayer();
332
332
  return { summary: "Rasterized" };
333
333
  }
@@ -419,7 +419,7 @@ function themeCommand(themes) {
419
419
  params: external_exports.object({ id: external_exports.string() }),
420
420
  expose: { ui: { label: "Theme", keywords: ["theme", "dark", "light", "comic", "appearance", "colors"], variants: themes.map((t) => ({ id: t.id, label: `Theme: ${t.name}`, params: { id: t.id } })) } },
421
421
  run: async ({ id }) => {
422
- (await import("./theme-store-FAYEXX7K.js")).useThemeStore.getState().setActiveTheme(id);
422
+ (await import("./theme-store-CBS2LI4H.js")).useThemeStore.getState().setActiveTheme(id);
423
423
  return { summary: `Theme: ${themes.find((t) => t.id === id)?.name ?? id}` };
424
424
  }
425
425
  });
@@ -438,7 +438,7 @@ function pluginCommand(plugins) {
438
438
  params: external_exports.object({ pluginId: external_exports.string(), commandId: external_exports.string() }),
439
439
  expose: { ui: { label: "Run plugin", keywords: ["plugin", "extension", "run"], variants, palette: variants.length ? void 0 : false } },
440
440
  run: async ({ pluginId, commandId }) => {
441
- await (await import("./host-PKGEIJZF.js")).runPlugin(pluginId, commandId);
441
+ await (await import("./host-VSSIPMLW.js")).runPlugin(pluginId, commandId);
442
442
  return { summary: "Plugin started" };
443
443
  }
444
444
  });
@@ -470,7 +470,7 @@ function registerAppCommands() {
470
470
  registerCommand(...appCommands);
471
471
  if (started || typeof window === "undefined") return;
472
472
  started = true;
473
- void import("./theme-store-FAYEXX7K.js").then(({ useThemeStore, pickableThemes }) => {
473
+ void import("./theme-store-CBS2LI4H.js").then(({ useThemeStore, pickableThemes }) => {
474
474
  const sync = () => registerCommand(themeCommand(pickableThemes(useThemeStore.getState())));
475
475
  sync();
476
476
  useThemeStore.subscribe(sync);
@@ -4,9 +4,6 @@ import { dirname as __popcraftDirname } from 'node:path';
4
4
  const require = __popcraftRequire(import.meta.url);
5
5
  const __filename = __popcraftPath(import.meta.url);
6
6
  const __dirname = __popcraftDirname(__filename);
7
- import {
8
- isAppleMobile
9
- } from "./chunk-ZBANBY2Q.js";
10
7
  import {
11
8
  createNewFileOrExplain,
12
9
  findLinkByKey,
@@ -16,14 +13,14 @@ import {
16
13
  reportOpenStage,
17
14
  setCloudLink,
18
15
  trackOpen
19
- } from "./chunk-QJU5LRJX.js";
16
+ } from "./chunk-ETC4DTCD.js";
20
17
  import {
21
18
  parseDeepLink,
22
19
  withDeepLink
23
20
  } from "./chunk-HFCMTDPQ.js";
24
21
  import {
25
22
  activeTeamWorkspaceId
26
- } from "./chunk-NH42V7UK.js";
23
+ } from "./chunk-7R77JLIP.js";
27
24
  import {
28
25
  ApiError,
29
26
  api,
@@ -31,9 +28,10 @@ import {
31
28
  } from "./chunk-7OJZZPU4.js";
32
29
  import {
33
30
  attachPresence
34
- } from "./chunk-N6T6XKGC.js";
31
+ } from "./chunk-GZWJRQRF.js";
35
32
  import {
36
33
  fileOpeningMode,
34
+ isAppleMobile,
37
35
  isPersistableDocument,
38
36
  isUnsavedPlaceholder,
39
37
  legacyYdocDatabase,
@@ -43,7 +41,7 @@ import {
43
41
  setCollabHistory,
44
42
  storedDocument,
45
43
  useEditorStore
46
- } from "./chunk-VRGEEHBR.js";
44
+ } from "./chunk-OK3DQPII.js";
47
45
  import {
48
46
  currentHistoryGroup
49
47
  } from "./chunk-DUH4J3CB.js";
@@ -26,10 +26,14 @@ import {
26
26
  stageFit,
27
27
  stageTarget,
28
28
  textLinkSource
29
- } from "./chunk-K63NQAOB.js";
29
+ } from "./chunk-XE6NJFI2.js";
30
30
  import {
31
- parseColor
32
- } from "./chunk-I5REOOP7.js";
31
+ BUILTIN_THEMES,
32
+ INITIAL_THEME_ID,
33
+ canvasColors,
34
+ parseColor,
35
+ resolveTheme
36
+ } from "./chunk-X4JKF2JG.js";
33
37
  import {
34
38
  seekTime,
35
39
  spanOf,
@@ -63,7 +67,7 @@ import {
63
67
  computeBooleanMultiPoly,
64
68
  nonzeroMultiPoly,
65
69
  require_polygon_clipping_cjs
66
- } from "./chunk-IIPH3CZZ.js";
70
+ } from "./chunk-IY5UZMTO.js";
67
71
  import {
68
72
  selectionWorldBounds
69
73
  } from "./chunk-TXEWYX4G.js";
@@ -82,17 +86,18 @@ import {
82
86
  import {
83
87
  snapToFrame
84
88
  } from "./chunk-W2P5XUAY.js";
89
+ import {
90
+ canBePixelLayer,
91
+ compositePixelLayers,
92
+ ensurePixelLayers,
93
+ layerInFrame
94
+ } from "./chunk-CMOVCY42.js";
85
95
  import {
86
96
  decodeImageUrl
87
97
  } from "./chunk-OD63RI3Y.js";
88
98
  import {
89
99
  getActiveRenderer
90
100
  } from "./chunk-A2DCJZGE.js";
91
- import {
92
- compositePixelLayers,
93
- ensurePixelLayers,
94
- layerInFrame
95
- } from "./chunk-CMOVCY42.js";
96
101
  import {
97
102
  cloudUser
98
103
  } from "./chunk-BXFKOMNU.js";
@@ -315,9 +320,11 @@ import {
315
320
  getAncestors,
316
321
  getNodeBounds,
317
322
  getRenderableNodes,
323
+ getWorldMatrix,
318
324
  getWorldRenderBounds,
319
325
  getWorldTransform,
320
326
  init_flatten,
327
+ init_glyph_linear,
321
328
  init_print_pages,
322
329
  init_routing,
323
330
  init_scene_graph,
@@ -390,6 +397,9 @@ import {
390
397
  shapeToVectorPath,
391
398
  writePath
392
399
  } from "./chunk-HOQFG5J7.js";
400
+ import {
401
+ init_layout_access
402
+ } from "./chunk-DC7CJQXE.js";
393
403
  import {
394
404
  init_time,
395
405
  localTime,
@@ -406,9 +416,16 @@ import {
406
416
  init_easing,
407
417
  interpOfEasing
408
418
  } from "./chunk-UHWYDCJ7.js";
419
+ import {
420
+ init_scene3d
421
+ } from "./chunk-DZHR24NY.js";
422
+ import {
423
+ init_transform3d
424
+ } from "./chunk-GHDFAWY2.js";
409
425
  import {
410
426
  apply,
411
- init_transform
427
+ init_transform,
428
+ invert
412
429
  } from "./chunk-5HGDT4AZ.js";
413
430
  import {
414
431
  init_dist_node,
@@ -432,6 +449,220 @@ import {
432
449
  // lib/store/editor-store.ts
433
450
  init_define_POPCRAFT_COMPONENT_IDS();
434
451
 
452
+ // lib/engine/camera.ts
453
+ init_define_POPCRAFT_COMPONENT_IDS();
454
+ function screenToWorld(screenX, screenY, camera, canvasWidth, canvasHeight) {
455
+ const ndcX = screenX / canvasWidth * 2 - 1;
456
+ const ndcY = screenY / canvasHeight * 2 - 1;
457
+ const halfWidth = canvasWidth / (2 * camera.zoom);
458
+ const halfHeight = canvasHeight / (2 * camera.zoom);
459
+ const worldX = ndcX * halfWidth + camera.x;
460
+ const worldY = ndcY * halfHeight + camera.y;
461
+ return { x: worldX, y: worldY };
462
+ }
463
+
464
+ // lib/editor/paste-place.ts
465
+ init_define_POPCRAFT_COMPONENT_IDS();
466
+ init_scene_graph();
467
+ init_transform();
468
+
469
+ // lib/editor/hit-test.ts
470
+ init_define_POPCRAFT_COMPONENT_IDS();
471
+
472
+ // lib/document/containers.ts
473
+ init_define_POPCRAFT_COMPONENT_IDS();
474
+
475
+ // lib/document/editability.ts
476
+ init_define_POPCRAFT_COMPONENT_IDS();
477
+ function isLocked(document2, nodeId) {
478
+ let id = nodeId;
479
+ const seen = /* @__PURE__ */ new Set();
480
+ while (id && !seen.has(id)) {
481
+ seen.add(id);
482
+ const node = document2.nodes[id];
483
+ if (!node) return false;
484
+ if (node.locked) return true;
485
+ id = node.parentId ?? void 0;
486
+ }
487
+ return false;
488
+ }
489
+ function editableIds(document2, ids) {
490
+ return ids.filter((id) => !isLocked(document2, id));
491
+ }
492
+ var NEVER_ROTATES = /* @__PURE__ */ new Set(["STICKY"]);
493
+ function canRotate(document2, nodeId) {
494
+ const node = document2.nodes[nodeId];
495
+ if (!node) return false;
496
+ return !NEVER_ROTATES.has(node.type) && !isLocked(document2, nodeId);
497
+ }
498
+
499
+ // lib/editor/hit-test.ts
500
+ init_scene_graph();
501
+ init_transform();
502
+ init_scene3d();
503
+ init_transform3d();
504
+
505
+ // lib/extensions/table/cell-text.ts
506
+ init_define_POPCRAFT_COMPONENT_IDS();
507
+ init_types();
508
+
509
+ // lib/editor/pointer/move/group-resize.ts
510
+ init_define_POPCRAFT_COMPONENT_IDS();
511
+
512
+ // lib/document/resize-children.ts
513
+ init_define_POPCRAFT_COMPONENT_IDS();
514
+
515
+ // lib/editor/pointer/move/group-resize.ts
516
+ init_scene_graph();
517
+
518
+ // lib/editor/pointer/move/snap.ts
519
+ init_define_POPCRAFT_COMPONENT_IDS();
520
+
521
+ // lib/engine/canvas-dpr.ts
522
+ init_define_POPCRAFT_COMPONENT_IDS();
523
+ function isAppleMobile() {
524
+ if (typeof navigator === "undefined") return false;
525
+ return /iPad|iPhone|iPod/.test(navigator.userAgent) || /Mac/.test(navigator.platform) && navigator.maxTouchPoints > 1;
526
+ }
527
+ function canvasDpr() {
528
+ if (typeof window === "undefined") return 1;
529
+ const dpr = window.devicePixelRatio || 1;
530
+ return dpr > 1 ? Math.max(1, dpr * renderScale) : dpr;
531
+ }
532
+ var renderScale = 1;
533
+
534
+ // lib/editor/hit-test.ts
535
+ init_layout_access();
536
+ init_glyph_linear();
537
+
538
+ // lib/editor/overlays/frame-labels.ts
539
+ init_define_POPCRAFT_COMPONENT_IDS();
540
+ init_scene_graph();
541
+
542
+ // lib/theme/chrome.ts
543
+ init_define_POPCRAFT_COMPONENT_IDS();
544
+ var defaults = resolveTheme(INITIAL_THEME_ID, (id) => BUILTIN_THEMES.find((t2) => t2.id === id));
545
+ var colors = canvasColors(defaults);
546
+
547
+ // lib/editor/hit-test.ts
548
+ function placement(state, nodeId, node) {
549
+ const t2 = getWorldTransform(state.document, nodeId);
550
+ return { m: unmirroredMatrix(t2, node.width, node.height), t: t2 };
551
+ }
552
+ function worldToNodeLocal(state, worldX, worldY, nodeId) {
553
+ const node = resolveVirtualNode(state.document.nodes, nodeId);
554
+ if (!node) return { x: worldX, y: worldY };
555
+ const inv = invert(placement(state, nodeId, node).m);
556
+ if (!inv) return { x: Infinity, y: Infinity };
557
+ const [x, y] = apply(inv, worldX, worldY);
558
+ return { x, y };
559
+ }
560
+ function getNodeWorldCenter(state, nodeId) {
561
+ const transform = getWorldTransform(state.document, nodeId);
562
+ return { x: transform.cx, y: transform.cy };
563
+ }
564
+ function findContainingFrame(state, nodeId) {
565
+ const node = state.document.nodes[nodeId];
566
+ if (!node) return null;
567
+ const allNodes = state.document.nodes;
568
+ const pageId = state.currentPageId;
569
+ const page = allNodes[pageId];
570
+ if (!page) return null;
571
+ const containers = [];
572
+ function collectContainers(ids) {
573
+ for (const id of ids) {
574
+ const n = allNodes[id];
575
+ if (!n) continue;
576
+ const parentType = n.parentId ? allNodes[n.parentId]?.type : void 0;
577
+ const topFrame = n.type === "FRAME" && (parentType === "PAGE" || parentType === "SECTION");
578
+ const acceptsNode = topFrame || n.type === "SECTION" || n.type === "PIXEL_GRID" && canBePixelLayer(node);
579
+ if (acceptsNode && id !== nodeId && id !== node.parentId) {
580
+ containers.push(n);
581
+ }
582
+ if (n.childIds && n.childIds.length > 0) collectContainers(n.childIds);
583
+ }
584
+ }
585
+ collectContainers(page.childIds);
586
+ const worldCenter = getNodeWorldCenter(state, nodeId);
587
+ const cx = worldCenter.x;
588
+ const cy = worldCenter.y;
589
+ let best = null;
590
+ let bestArea = Infinity;
591
+ for (const container of containers) {
592
+ const cCenter = getNodeWorldCenter(state, container.id);
593
+ const cWorldX = cCenter.x - container.width / 2;
594
+ const cWorldY = cCenter.y - container.height / 2;
595
+ if (cx >= cWorldX && cx <= cWorldX + container.width && cy >= cWorldY && cy <= cWorldY + container.height) {
596
+ const area2 = container.width * container.height;
597
+ if (area2 < bestArea) {
598
+ bestArea = area2;
599
+ best = container;
600
+ }
601
+ }
602
+ }
603
+ return best ? best.id : null;
604
+ }
605
+ function findCreationParent(state, nodeId) {
606
+ const node = state.document.nodes[nodeId];
607
+ if (!node) return null;
608
+ const nodes = state.document.nodes;
609
+ const c = getNodeWorldCenter(state, nodeId);
610
+ let best = null;
611
+ let bestDepth = -1;
612
+ const visit = (id, depth) => {
613
+ const n = nodes[id];
614
+ if (!n || id === nodeId || !n.visible || n.locked) return;
615
+ const ok = node.type === "SECTION" ? n.type === "SECTION" : n.type === "FRAME" || n.type === "SECTION" || n.type === "COMPONENT";
616
+ if (ok) {
617
+ const p = worldToNodeLocal(state, c.x, c.y, id);
618
+ if (p.x >= 0 && p.y >= 0 && p.x <= n.width && p.y <= n.height && depth > bestDepth) {
619
+ best = id;
620
+ bestDepth = depth;
621
+ }
622
+ }
623
+ if (n.type === "FRAME" || n.type === "SECTION" || n.type === "COMPONENT") for (const k of n.childIds ?? []) visit(k, depth + 1);
624
+ };
625
+ for (const id of nodes[state.currentPageId]?.childIds ?? []) visit(id, 0);
626
+ return best;
627
+ }
628
+
629
+ // lib/editor/paste-place.ts
630
+ var inside = (b, c) => b.minX >= c.minX - 0.5 && b.minY >= c.minY - 0.5 && b.maxX <= c.maxX + 0.5 && b.maxY <= c.maxY + 0.5;
631
+ var overlaps = (b, c) => b.maxX > c.minX && b.minX < c.maxX && b.maxY > c.minY && b.minY < c.maxY;
632
+ function placePasted(doc, pageId, ids, view, opts = {}) {
633
+ if (!ids.length) return doc;
634
+ const parentId = doc.nodes[ids[0]]?.parentId;
635
+ if (!parentId) return doc;
636
+ const onPage = doc.nodes[parentId]?.type === "PAGE";
637
+ const b = selectionWorldBounds(doc.nodes, ids);
638
+ const c = onPage ? view : selectionWorldBounds(doc.nodes, [parentId]);
639
+ if (b && c && (opts.centre || (onPage ? !overlaps(b, c) : !inside(b, c)))) {
640
+ const dx = (c.minX + c.maxX) / 2 - (b.minX + b.maxX) / 2;
641
+ const dy = (c.minY + c.maxY) / 2 - (b.minY + b.maxY) / 2;
642
+ const inv = onPage ? null : invert(getWorldMatrix(doc, parentId));
643
+ const [ox, oy] = inv ? apply(inv, 0, 0) : [0, 0];
644
+ const [lx, ly] = inv ? apply(inv, dx, dy) : [dx, dy];
645
+ for (const id of ids) {
646
+ const n = doc.nodes[id];
647
+ doc = updateNode(doc, id, { x: n.x + (lx - ox), y: n.y + (ly - oy) });
648
+ }
649
+ }
650
+ if (onPage) return doc;
651
+ const within = (id) => {
652
+ for (let p = id; p; p = doc.nodes[p]?.parentId) if (p === parentId) return true;
653
+ return false;
654
+ };
655
+ for (const id of ids) {
656
+ const state = { document: doc, currentPageId: pageId, camera: { x: 0, y: 0, zoom: 1 } };
657
+ const target = findCreationParent(state, id);
658
+ if (!target || target === doc.nodes[id]?.parentId || !within(target)) continue;
659
+ const placed2 = placementUnder(doc, id, target);
660
+ if (placed2) doc = updateNode(doc, id, placed2);
661
+ doc = reparentNode(doc, id, target);
662
+ }
663
+ return doc;
664
+ }
665
+
435
666
  // lib/editor/selection-drill.ts
436
667
  init_define_POPCRAFT_COMPONENT_IDS();
437
668
  init_scene_graph();
@@ -481,30 +712,6 @@ function prefersReducedMotion(prefs = getA11yPrefs()) {
481
712
  return prefs.motion === "reduce" || prefs.motion === "system" && media(REDUCED_QUERY);
482
713
  }
483
714
 
484
- // lib/document/editability.ts
485
- init_define_POPCRAFT_COMPONENT_IDS();
486
- function isLocked(document2, nodeId) {
487
- let id = nodeId;
488
- const seen = /* @__PURE__ */ new Set();
489
- while (id && !seen.has(id)) {
490
- seen.add(id);
491
- const node = document2.nodes[id];
492
- if (!node) return false;
493
- if (node.locked) return true;
494
- id = node.parentId ?? void 0;
495
- }
496
- return false;
497
- }
498
- function editableIds(document2, ids) {
499
- return ids.filter((id) => !isLocked(document2, id));
500
- }
501
- var NEVER_ROTATES = /* @__PURE__ */ new Set(["STICKY"]);
502
- function canRotate(document2, nodeId) {
503
- const node = document2.nodes[nodeId];
504
- if (!node) return false;
505
- return !NEVER_ROTATES.has(node.type) && !isLocked(document2, nodeId);
506
- }
507
-
508
715
  // node_modules/.pnpm/zustand@5.0.15_@types+react@19.3.0_immer@11.1.21_react@19.3.0_use-sync-external-store@1.6.0_react@19.3.0_/node_modules/zustand/esm/middleware.mjs
509
716
  init_define_POPCRAFT_COMPONENT_IDS();
510
717
  var subscribeWithSelectorImpl = (fn) => (set2, get2, api) => {
@@ -2187,11 +2394,11 @@ function arrangementFaces(shapes) {
2187
2394
  const next = [];
2188
2395
  let rest = shape;
2189
2396
  for (const f of faces) {
2190
- const inside = op(import_polygon_clipping.default.intersection, f.mp, shape);
2191
- if (solid(inside)) next.push({ mp: inside, sources: [...f.sources, i] });
2397
+ const inside2 = op(import_polygon_clipping.default.intersection, f.mp, shape);
2398
+ if (solid(inside2)) next.push({ mp: inside2, sources: [...f.sources, i] });
2192
2399
  const outside = op(import_polygon_clipping.default.difference, f.mp, shape);
2193
2400
  if (solid(outside)) next.push({ mp: outside, sources: f.sources });
2194
- if (solid(inside)) rest = op(import_polygon_clipping.default.difference, rest, f.mp);
2401
+ if (solid(inside2)) rest = op(import_polygon_clipping.default.difference, rest, f.mp);
2195
2402
  }
2196
2403
  if (solid(rest)) next.push({ mp: rest, sources: [i] });
2197
2404
  faces = next;
@@ -2200,15 +2407,15 @@ function arrangementFaces(shapes) {
2200
2407
  }
2201
2408
  function pointInMultiPoly(mp, x, y) {
2202
2409
  for (const poly of mp) {
2203
- let inside = false;
2410
+ let inside2 = false;
2204
2411
  for (const ring of poly) {
2205
2412
  for (let i = 0, j = ring.length - 1; i < ring.length; j = i++) {
2206
2413
  const [xi, yi] = ring[i];
2207
2414
  const [xj, yj] = ring[j];
2208
- if (yi > y !== yj > y && x < (xj - xi) * (y - yi) / (yj - yi) + xi) inside = !inside;
2415
+ if (yi > y !== yj > y && x < (xj - xi) * (y - yi) / (yj - yi) + xi) inside2 = !inside2;
2209
2416
  }
2210
2417
  }
2211
- if (inside) return true;
2418
+ if (inside2) return true;
2212
2419
  }
2213
2420
  return false;
2214
2421
  }
@@ -3915,8 +4122,8 @@ function createPixelSlice(set2, get2) {
3915
4122
  pixelAddTag: (id, from, to) => {
3916
4123
  const n = node(id);
3917
4124
  if (!n) return;
3918
- const colors = ["#e9720c", "#0c8ce9", "#34c759", "#af52de", "#ff2d55", "#ffcc00"];
3919
- const tag = { id: v4_default(), name: `Tag ${n.tags.length + 1}`, from: clampFrame(n, Math.min(from, to)), to: clampFrame(n, Math.max(from, to)), direction: "FORWARD", color: colors[n.tags.length % colors.length] };
4125
+ const colors2 = ["#e9720c", "#0c8ce9", "#34c759", "#af52de", "#ff2d55", "#ffcc00"];
4126
+ const tag = { id: v4_default(), name: `Tag ${n.tags.length + 1}`, from: clampFrame(n, Math.min(from, to)), to: clampFrame(n, Math.max(from, to)), direction: "FORWARD", color: colors2[n.tags.length % colors2.length] };
3920
4127
  commit(id, { tags: [...n.tags, tag] }, "Add tag");
3921
4128
  },
3922
4129
  pixelUpdateTag: (id, tagId, patch) => {
@@ -4551,8 +4758,8 @@ function washiOutline(length, width, seed, edge = "SPIKY") {
4551
4758
  }
4552
4759
  function washiFill(style, width, seed) {
4553
4760
  if (style.pattern) {
4554
- const colors = paletteColors(style.palette ?? "denim");
4555
- return { type: "PATTERN", visible: true, opacity: 1, patternPreset: style.pattern, patternColors: colors, patternScale: Math.max(0.3, Math.min(3, width / 36)) };
4761
+ const colors2 = paletteColors(style.palette ?? "denim");
4762
+ return { type: "PATTERN", visible: true, opacity: 1, patternPreset: style.pattern, patternColors: colors2, patternScale: Math.max(0.3, Math.min(3, width / 36)) };
4556
4763
  }
4557
4764
  const color = style.color ?? { r: 0.97, g: 0.62, b: 0.7, a: 1 };
4558
4765
  const tex = {
@@ -4630,7 +4837,7 @@ function createPopcornSlice(set2, get2) {
4630
4837
  privateMode: false,
4631
4838
  setPrivateMode: (on) => {
4632
4839
  set2({ privateMode: on });
4633
- void import("./presence-TL24PA2T.js").then((m) => m.setPresencePrivate(on)).catch(() => {
4840
+ void import("./presence-GGLTIRS2.js").then((m) => m.setPresencePrivate(on)).catch(() => {
4634
4841
  });
4635
4842
  },
4636
4843
  /** Reveal every private item THIS user created (they sync to collaborators). Others' stay theirs. */
@@ -6675,7 +6882,7 @@ var useEditorStore = create()(
6675
6882
  // A copy is a new file, so it is cloud-backed like any other (see lib/client/cloud/new-file.ts).
6676
6883
  // Returns '' when it was refused (offline, signed out, plan full) or failed; nothing is left behind.
6677
6884
  duplicateDocument: async (id) => {
6678
- const { duplicateDocumentToCloud } = await import("./sync-PQCW3ZLW.js");
6885
+ const { duplicateDocumentToCloud } = await import("./sync-K2VRUB23.js");
6679
6886
  return duplicateDocumentToCloud(id);
6680
6887
  },
6681
6888
  deleteDocument: async (id) => {
@@ -7565,6 +7772,14 @@ var useEditorStore = create()(
7565
7772
  doc = { ...doc, nodes: newNodes };
7566
7773
  doc = relinkCopies(doc, idMap);
7567
7774
  doc = adoptPastedLibraryInstances(doc, newSelection, carried, libraryLink());
7775
+ {
7776
+ const vp = canvasViewport();
7777
+ const a = screenToWorld(0, 0, state.camera, vp.width, vp.height);
7778
+ const z = screenToWorld(vp.width, vp.height, state.camera, vp.width, vp.height);
7779
+ const view = { minX: Math.min(a.x, z.x), minY: Math.min(a.y, z.y), maxX: Math.max(a.x, z.x), maxY: Math.max(a.y, z.y) };
7780
+ const fromElsewhere = !!into && into.type === "SECTION" && topLevelNodes.every((n) => n.parentId !== into.id);
7781
+ doc = placePasted(doc, state.currentPageId, newSelection.filter((id) => doc.nodes[id]), view, { centre: fromElsewhere });
7782
+ }
7568
7783
  const command = createCommand("PASTE_NODES", `Paste ${topLevelNodes.length} node(s)`, documentBefore, doc);
7569
7784
  set2({
7570
7785
  document: applyAutoLayout(doc),
@@ -10171,9 +10386,9 @@ if (typeof window !== "undefined") {
10171
10386
  if (typeof window !== "undefined" && navigator.webdriver) {
10172
10387
  window.__vpDesign = async (script, o = {}) => {
10173
10388
  const [{ registerBuiltinTools, runTool }, { editorToolContext }, { createDesignPreview }] = await Promise.all([
10174
- import("./tools-HBJ2I7YP.js").then(async (m) => ({ ...m, registerBuiltinTools: (await import("./builtin-O5D2Q6RV.js")).registerBuiltinTools })),
10175
- import("./editor-seams-AFXFNM6K.js"),
10176
- import("./live-X3AP4MHF.js")
10389
+ import("./tools-JRQSLBJK.js").then(async (m) => ({ ...m, registerBuiltinTools: (await import("./builtin-5P5A2IMY.js")).registerBuiltinTools })),
10390
+ import("./editor-seams-4M7R4HNW.js"),
10391
+ import("./live-DQITX7DB.js")
10177
10392
  ]);
10178
10393
  registerBuiltinTools();
10179
10394
  const args = JSON.stringify({ ...o.name ? { name: o.name } : {}, ...o.size ? { size: o.size } : {}, ...o.frame ? { frame: o.frame } : {}, script });
@@ -10230,7 +10445,7 @@ if (typeof window !== "undefined" && navigator.webdriver) {
10230
10445
  return { type, width: spec.width, height: spec.height, b64: btoa(bin) };
10231
10446
  };
10232
10447
  window.__vpLottieCheck = async (what, at) => {
10233
- const [{ lottieCheckFrames }, { getActiveRenderer: getActiveRenderer2 }] = await Promise.all([import("./player-check-ZGWLAHXY.js"), import("./renderer-registry-UWFTNNVB.js")]);
10448
+ const [{ lottieCheckFrames }, { getActiveRenderer: getActiveRenderer2 }] = await Promise.all([import("./player-check-CZVWUJXW.js"), import("./renderer-registry-UWFTNNVB.js")]);
10234
10449
  const renderer = getActiveRenderer2();
10235
10450
  if (!renderer) throw new Error("no renderer on this route");
10236
10451
  const doc = useEditorStore.getState().document;
@@ -10442,6 +10657,10 @@ onWriteFromReadOnly(() => {
10442
10657
  });
10443
10658
 
10444
10659
  export {
10660
+ screenToWorld,
10661
+ isAppleMobile,
10662
+ canvasDpr,
10663
+ findContainingFrame,
10445
10664
  fileOpeningMode,
10446
10665
  RASTER_MAX_SIDE,
10447
10666
  setPluginTabs,
@@ -8,9 +8,7 @@ import {
8
8
  BUILTIN_THEMES,
9
9
  DEFAULT_THEME_ID,
10
10
  INITIAL_THEME_ID,
11
- PICKABLE_BUILTIN_IDS
12
- } from "./chunk-XKUI2K2V.js";
13
- import {
11
+ PICKABLE_BUILTIN_IDS,
14
12
  TOKENS,
15
13
  collectCss,
16
14
  collectFonts,
@@ -18,7 +16,7 @@ import {
18
16
  resolveTheme,
19
17
  toCssVars,
20
18
  tokenVar
21
- } from "./chunk-I5REOOP7.js";
19
+ } from "./chunk-X4JKF2JG.js";
22
20
  import {
23
21
  create
24
22
  } from "./chunk-RVNIEOXA.js";