@input/pen-core 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -141,6 +141,8 @@ __export(index_exports, {
141
141
  interpolateMessage: () => interpolateMessage,
142
142
  isBlockSelected: () => isBlockSelected,
143
143
  isCollapsed: () => isCollapsed,
144
+ isContainerBlock: () => isContainerBlock,
145
+ isContainerBlockType: () => isContainerBlockType,
144
146
  isContinuousTextFlowCapability: () => isContinuousTextFlowCapability,
145
147
  isMultiBlock: () => isMultiBlock,
146
148
  isPseudoLocaleText: () => isPseudoLocaleText,
@@ -157,6 +159,7 @@ __export(index_exports, {
157
159
  nextGraphemeBoundary: () => nextGraphemeBoundary,
158
160
  nextWordBoundary: () => nextWordBoundary,
159
161
  normalizePendingBlocksForImport: () => normalizePendingBlocksForImport,
162
+ orderSlashMenuItemsByGroup: () => orderSlashMenuItemsByGroup,
160
163
  outdent: () => outdent,
161
164
  previousGraphemeBoundary: () => previousGraphemeBoundary,
162
165
  previousWordBoundary: () => previousWordBoundary,
@@ -199,8 +202,10 @@ __export(index_exports, {
199
202
  shouldAllowFlowInsertionInSlashMenu: () => shouldAllowFlowInsertionInSlashMenu,
200
203
  shouldExposeBlockInTooling: () => shouldExposeBlockInTooling,
201
204
  shouldForceBlockScopedSelectAll: () => shouldForceBlockScopedSelectAll,
205
+ shouldRenderContainerChildren: () => shouldRenderContainerChildren,
202
206
  shouldShowBlockInDefaultMenus: () => shouldShowBlockInDefaultMenus,
203
207
  singleController: () => singleController,
208
+ slashMenuGroupOf: () => slashMenuGroupOf,
204
209
  snapToNormalPosition: () => snapToNormalPosition,
205
210
  snapshotsControllerFacet: () => snapshotsControllerFacet,
206
211
  sortDeltaAttributes: () => sortDeltaAttributes,
@@ -923,6 +928,25 @@ function mergeSchemas(...registries2) {
923
928
  });
924
929
  }
925
930
 
931
+ // src/schema/slashMenuOrder.ts
932
+ var FALLBACK_GROUP = "other";
933
+ function slashMenuGroupOf(display) {
934
+ return display.group ?? FALLBACK_GROUP;
935
+ }
936
+ function orderSlashMenuItemsByGroup(items) {
937
+ const grouped = /* @__PURE__ */ new Map();
938
+ for (const item of items) {
939
+ const group = slashMenuGroupOf(item.display);
940
+ const existing = grouped.get(group);
941
+ if (existing) {
942
+ existing.push(item);
943
+ } else {
944
+ grouped.set(group, [item]);
945
+ }
946
+ }
947
+ return [...grouped.values()].flat();
948
+ }
949
+
926
950
  // src/schema/defineBlock.ts
927
951
  function resolveProps2(config) {
928
952
  const raw = config.props ?? config.propSchema ?? {};
@@ -1202,6 +1226,15 @@ var SchemaEngineImpl = class {
1202
1226
  markDirty(blockId) {
1203
1227
  this.dirtyBlockIds.add(blockId);
1204
1228
  }
1229
+ /**
1230
+ * Drop the cached pass index because `blockOrder` or a `children` array
1231
+ * changed outside this engine — an executing op, or a remote/undo update.
1232
+ * Every structural mutation the engine performs itself already invalidates
1233
+ * at the mutation site, so those callers do not go through here.
1234
+ */
1235
+ notifyStructureChanged() {
1236
+ this.invalidatePassIndex();
1237
+ }
1205
1238
  deferBlock(blockId) {
1206
1239
  this.deferredBlockIds.add(blockId);
1207
1240
  }
@@ -1221,7 +1254,6 @@ var SchemaEngineImpl = class {
1221
1254
  }
1222
1255
  iterations++;
1223
1256
  this.dirtyBlockIds.clear();
1224
- this.invalidatePassIndex();
1225
1257
  this.doc.adapter.transact(this.crdtDoc, () => {
1226
1258
  for (const blockId of snapshot) {
1227
1259
  if (this.deferredBlockIds.has(blockId)) {
@@ -1232,7 +1264,6 @@ var SchemaEngineImpl = class {
1232
1264
  }
1233
1265
  });
1234
1266
  }
1235
- this.invalidatePassIndex();
1236
1267
  if (iterations >= MAX_ITERATIONS) {
1237
1268
  this.onDiagnostic?.({
1238
1269
  code: "normalize-cap",
@@ -1244,6 +1275,7 @@ var SchemaEngineImpl = class {
1244
1275
  }
1245
1276
  }
1246
1277
  normalizeAll() {
1278
+ this.invalidatePassIndex();
1247
1279
  for (const blockId of this.doc.blocks.keys()) {
1248
1280
  this.dirtyBlockIds.add(blockId);
1249
1281
  }
@@ -2156,7 +2188,7 @@ function schemaDeclaresBlockCapability(schema, capability) {
2156
2188
  }
2157
2189
 
2158
2190
  // src/editor/editor.ts
2159
- var import_pen_types10 = require("@input/pen-types");
2191
+ var import_pen_types11 = require("@input/pen-types");
2160
2192
  var import_pen_yjs8 = require("@input/pen-yjs");
2161
2193
 
2162
2194
  // src/editor/events.ts
@@ -2901,6 +2933,7 @@ function opBlockId(_pipeline, op) {
2901
2933
  var import_pen_yjs = require("@input/pen-yjs");
2902
2934
 
2903
2935
  // src/schema/contentType.ts
2936
+ var import_pen_types2 = require("@input/pen-types");
2904
2937
  function resolveRuntimeContentType(schema) {
2905
2938
  if (!schema) {
2906
2939
  return "none";
@@ -2910,6 +2943,10 @@ function resolveRuntimeContentType(schema) {
2910
2943
  }
2911
2944
  return schema.content;
2912
2945
  }
2946
+ function isContainerBlock(schema) {
2947
+ if (!schema) return false;
2948
+ return (0, import_pen_types2.isNestedContent)(schema.content) || schema.isContainer === true;
2949
+ }
2913
2950
 
2914
2951
  // src/editor/rejectedOwnKeys.ts
2915
2952
  var REJECTED_OWN_PROP_KEYS = /* @__PURE__ */ new Set([
@@ -3456,6 +3493,11 @@ function emitSchemaUnknownBlock(pipeline, type) {
3456
3493
  });
3457
3494
  }
3458
3495
  function reportUnknownBlocksInDocument(pipeline) {
3496
+ const blockCount = pipeline._doc.blocks.size;
3497
+ if (blockCount === pipeline._unknownScanBlockCount) {
3498
+ return;
3499
+ }
3500
+ pipeline._unknownScanBlockCount = blockCount;
3459
3501
  for (const [, rawBlockMap] of pipeline._doc.blocks.entries()) {
3460
3502
  if (!isCRDTMap(rawBlockMap)) {
3461
3503
  continue;
@@ -3755,6 +3797,9 @@ function emitMalformedOpDiagnostic(pipeline, op, error) {
3755
3797
  ...error !== void 0 ? { error } : {}
3756
3798
  });
3757
3799
  }
3800
+ function isStructuralOp(op) {
3801
+ return op.type === "insert-block" || op.type === "delete-block" || op.type === "move-block";
3802
+ }
3758
3803
  function executeOps(pipeline, ops, origin, structural) {
3759
3804
  pipeline._commitDiagnostics = [];
3760
3805
  reportUnknownBlocksInDocument(pipeline);
@@ -3776,6 +3821,15 @@ function executeOps(pipeline, ops, origin, structural) {
3776
3821
  const blockId = opBlockId(pipeline, op);
3777
3822
  if (!validateOp(pipeline, op)) continue;
3778
3823
  if (op.type === "insert-block") {
3824
+ if (blockExists(pipeline, op.blockId) || pendingBlockIds.has(op.blockId)) {
3825
+ emitPipelineDiagnostic(pipeline, {
3826
+ code: "PEN_APPLY_010",
3827
+ level: "warn",
3828
+ source: "apply",
3829
+ message: `apply: skipping insert-block for already-present block "${op.blockId}"`
3830
+ });
3831
+ continue;
3832
+ }
3779
3833
  pendingBlockIds.add(op.blockId);
3780
3834
  pendingBlockTypes.set(op.blockId, op.blockType);
3781
3835
  }
@@ -3821,6 +3875,9 @@ function executeOps(pipeline, ops, origin, structural) {
3821
3875
  } catch (err) {
3822
3876
  emitMalformedOpDiagnostic(pipeline, op, err);
3823
3877
  }
3878
+ if (isStructuralOp(op)) {
3879
+ pipeline._engine.notifyStructureChanged();
3880
+ }
3824
3881
  }
3825
3882
  for (const blockId of affectedBlocks) {
3826
3883
  pipeline._engine.markDirty(blockId);
@@ -3992,6 +4049,7 @@ var ApplyPipeline = class {
3992
4049
  _applyStormEmitted = false;
3993
4050
  _suppressObserver = false;
3994
4051
  _unknownBlockTypesReported;
4052
+ _unknownScanBlockCount;
3995
4053
  _queue = [];
3996
4054
  _applyBoundaryHooks = [];
3997
4055
  _beforeApplyHooks = [];
@@ -4075,6 +4133,7 @@ var ApplyPipeline = class {
4075
4133
  this._doc = doc;
4076
4134
  this._crdtDoc = crdtDoc;
4077
4135
  this._engine = engine;
4136
+ this._unknownScanBlockCount = void 0;
4078
4137
  }
4079
4138
  };
4080
4139
 
@@ -6236,9 +6295,11 @@ var SelectionAuthorityImpl = class {
6236
6295
  };
6237
6296
 
6238
6297
  // src/editor/documentState.ts
6298
+ var EMPTY_CHILD_IDS = Object.freeze([]);
6239
6299
  var DocumentStateImpl = class {
6240
6300
  _positionIndex;
6241
6301
  _parentIndex;
6302
+ _childIndex;
6242
6303
  _blockOrder;
6243
6304
  _generation = 0;
6244
6305
  _documentProfile;
@@ -6252,6 +6313,7 @@ var DocumentStateImpl = class {
6252
6313
  this._documentProfile = documentProfile;
6253
6314
  this._positionIndex = /* @__PURE__ */ new Map();
6254
6315
  this._parentIndex = /* @__PURE__ */ new Map();
6316
+ this._childIndex = /* @__PURE__ */ new Map();
6255
6317
  this._blockOrder = [];
6256
6318
  this.rebuild();
6257
6319
  }
@@ -6290,6 +6352,9 @@ var DocumentStateImpl = class {
6290
6352
  parentOf(blockId) {
6291
6353
  return this._parentIndex.get(blockId) ?? null;
6292
6354
  }
6355
+ childrenOf(blockId) {
6356
+ return this._childIndex.get(blockId) ?? EMPTY_CHILD_IDS;
6357
+ }
6293
6358
  *allBlocks() {
6294
6359
  const seen = /* @__PURE__ */ new Set();
6295
6360
  for (const id of this._blockOrder) {
@@ -6309,21 +6374,44 @@ var DocumentStateImpl = class {
6309
6374
  this._blockOrder = [];
6310
6375
  this._positionIndex = /* @__PURE__ */ new Map();
6311
6376
  this._parentIndex = /* @__PURE__ */ new Map();
6377
+ this._childIndex = /* @__PURE__ */ new Map();
6312
6378
  for (let i = 0; i < order.length; i++) {
6313
6379
  const id = order.get(i);
6314
6380
  this._blockOrder.push(id);
6315
6381
  this._positionIndex.set(id, i);
6316
6382
  }
6383
+ const nestedChildIds = /* @__PURE__ */ new Set();
6384
+ const parentIdChildIds = [];
6317
6385
  for (const [blockId, blockMap] of this._doc.blocks.entries()) {
6318
6386
  const props = blockMap.get("props");
6319
6387
  if (props?.get?.("parentId")) {
6320
6388
  this._parentIndex.set(blockId, props.get("parentId"));
6389
+ parentIdChildIds.push(blockId);
6321
6390
  }
6322
6391
  const children = blockMap.get("children");
6323
- if (children) {
6392
+ if (children && children.length > 0) {
6393
+ const childIds = [];
6324
6394
  for (let i = 0; i < children.length; i++) {
6325
- this._parentIndex.set(children.get(i), blockId);
6395
+ const childId = children.get(i);
6396
+ this._parentIndex.set(childId, blockId);
6397
+ nestedChildIds.add(childId);
6398
+ childIds.push(childId);
6326
6399
  }
6400
+ this._childIndex.set(blockId, childIds);
6401
+ }
6402
+ }
6403
+ parentIdChildIds.sort(
6404
+ (a, b) => (this._positionIndex.get(a) ?? -1) - (this._positionIndex.get(b) ?? -1)
6405
+ );
6406
+ for (const childId of parentIdChildIds) {
6407
+ if (nestedChildIds.has(childId)) continue;
6408
+ const parentId = this._parentIndex.get(childId);
6409
+ if (parentId === void 0) continue;
6410
+ const siblings = this._childIndex.get(parentId);
6411
+ if (siblings === void 0) {
6412
+ this._childIndex.set(parentId, [childId]);
6413
+ } else {
6414
+ siblings.push(childId);
6327
6415
  }
6328
6416
  }
6329
6417
  this._generation++;
@@ -6331,6 +6419,7 @@ var DocumentStateImpl = class {
6331
6419
  clear() {
6332
6420
  this._positionIndex.clear();
6333
6421
  this._parentIndex.clear();
6422
+ this._childIndex.clear();
6334
6423
  this._blockOrder = [];
6335
6424
  this._generation++;
6336
6425
  }
@@ -7554,7 +7643,7 @@ function sameIdList(left, right) {
7554
7643
  }
7555
7644
 
7556
7645
  // src/facets/i18nFacets.ts
7557
- var import_pen_types2 = require("@input/pen-types");
7646
+ var import_pen_types3 = require("@input/pen-types");
7558
7647
  function resolveEnvironmentLocale() {
7559
7648
  if (typeof navigator === "object" && navigator !== null) {
7560
7649
  const language = navigator.language;
@@ -7572,7 +7661,7 @@ var messagesFacet = defineFacet({
7572
7661
  name: "pen.messages",
7573
7662
  combine: (inputs) => {
7574
7663
  const catalog = {
7575
- ...import_pen_types2.DEFAULT_MESSAGE_CATALOG
7664
+ ...import_pen_types3.DEFAULT_MESSAGE_CATALOG
7576
7665
  };
7577
7666
  for (let index = inputs.length - 1; index >= 0; index -= 1) {
7578
7667
  Object.assign(catalog, inputs[index]);
@@ -7594,11 +7683,18 @@ var BACKSPACE_EXIT_TYPES = /* @__PURE__ */ new Set([
7594
7683
  ...CONTAINER_EXIT_TYPES,
7595
7684
  ...HEADING_TYPES
7596
7685
  ]);
7597
- var PARENT_ID_CONTAINER_TYPES = /* @__PURE__ */ new Set([
7598
- "toggle",
7599
- "callout",
7600
- "blockquote"
7601
- ]);
7686
+ function isContainerBlockType(editor, blockType) {
7687
+ if (!blockType) {
7688
+ return false;
7689
+ }
7690
+ return isContainerBlock(editor.schema.resolve(blockType));
7691
+ }
7692
+ function shouldRenderContainerChildren(editor, block) {
7693
+ if (!block || !isContainerBlockType(editor, block.type)) {
7694
+ return false;
7695
+ }
7696
+ return block.props?.open !== false;
7697
+ }
7602
7698
  function emitCommandDiagnostic(editor, event) {
7603
7699
  editor.internals?.emit("diagnostic", event);
7604
7700
  }
@@ -7650,18 +7746,13 @@ function isInsideParentIdContainer(editor, blockId) {
7650
7746
  return false;
7651
7747
  }
7652
7748
  const parent = editor.getBlock(parentId);
7653
- return !!parent && PARENT_ID_CONTAINER_TYPES.has(parent.type);
7749
+ return !!parent && isContainerBlockType(editor, parent.type);
7654
7750
  }
7655
7751
  function getRootBlockIds(editor) {
7656
7752
  return editor.documentState.blockOrder.filter(
7657
7753
  (blockId) => editor.documentState.parentOf(blockId) == null
7658
7754
  );
7659
7755
  }
7660
- function getParentIdChildBlockIds(editor, parentBlockId) {
7661
- return editor.documentState.blockOrder.filter(
7662
- (blockId) => editor.documentState.parentOf(blockId) === parentBlockId
7663
- );
7664
- }
7665
7756
  function getVisibleBlockIds(editor) {
7666
7757
  const visibleBlockIds = [];
7667
7758
  for (const rootBlockId of getRootBlockIds(editor)) {
@@ -7783,23 +7874,13 @@ function convertBlockOps(editor, options) {
7783
7874
  }
7784
7875
  function collectVisibleBlockIds(editor, blockId, visibleBlockIds) {
7785
7876
  visibleBlockIds.push(blockId);
7786
- if (!shouldShowParentIdChildren(editor, blockId)) {
7877
+ if (!shouldRenderContainerChildren(editor, editor.getBlock(blockId))) {
7787
7878
  return;
7788
7879
  }
7789
- for (const childBlockId of getParentIdChildBlockIds(editor, blockId)) {
7880
+ for (const childBlockId of editor.documentState.childrenOf(blockId)) {
7790
7881
  collectVisibleBlockIds(editor, childBlockId, visibleBlockIds);
7791
7882
  }
7792
7883
  }
7793
- function shouldShowParentIdChildren(editor, blockId) {
7794
- const block = editor.getBlock(blockId);
7795
- if (!block || !PARENT_ID_CONTAINER_TYPES.has(block.type)) {
7796
- return false;
7797
- }
7798
- if (block.type !== "toggle") {
7799
- return true;
7800
- }
7801
- return Boolean(block.props?.open);
7802
- }
7803
7884
 
7804
7885
  // src/commands/commandSelection.ts
7805
7886
  function textSelectionResult(anchor, focus = anchor, extras) {
@@ -7975,12 +8056,12 @@ function parentContainerKind(editor, parentId) {
7975
8056
  if (!parent) {
7976
8057
  return null;
7977
8058
  }
7978
- if (PARENT_ID_CONTAINER_TYPES.has(parent.type)) {
7979
- return "layout-cell";
7980
- }
7981
8059
  if (parent.type === "table") {
7982
8060
  return "table";
7983
8061
  }
8062
+ if (isContainerBlockType(editor, parent.type)) {
8063
+ return "layout-cell";
8064
+ }
7984
8065
  return null;
7985
8066
  }
7986
8067
 
@@ -9193,7 +9274,7 @@ function isUndoManager(value) {
9193
9274
  }
9194
9275
 
9195
9276
  // src/commands/structure.ts
9196
- var import_pen_types3 = require("@input/pen-types");
9277
+ var import_pen_types4 = require("@input/pen-types");
9197
9278
  var moveBlockUp = defineCommand("pen.moveBlockUp");
9198
9279
  var moveBlockDown = defineCommand("pen.moveBlockDown");
9199
9280
  var duplicateBlock = defineCommand("pen.duplicateBlock");
@@ -9244,7 +9325,7 @@ function handleDuplicateBlock(editor, param) {
9244
9325
  if (!block) {
9245
9326
  return false;
9246
9327
  }
9247
- const newBlockId = (0, import_pen_types3.generateId)();
9328
+ const newBlockId = (0, import_pen_types4.generateId)();
9248
9329
  const ops = [
9249
9330
  {
9250
9331
  type: "insert-block",
@@ -9277,7 +9358,7 @@ function handleDeleteBlock(editor, param) {
9277
9358
  (blockId) => !blockIds.includes(blockId)
9278
9359
  );
9279
9360
  if (remaining.length === 0) {
9280
- const replacementId = (0, import_pen_types3.generateId)();
9361
+ const replacementId = (0, import_pen_types4.generateId)();
9281
9362
  editor.apply(
9282
9363
  [
9283
9364
  {
@@ -9851,7 +9932,7 @@ function deleteSelectedBlocks(editor, blockIds) {
9851
9932
  }
9852
9933
 
9853
9934
  // src/commands/textEnter.ts
9854
- var import_pen_types4 = require("@input/pen-types");
9935
+ var import_pen_types5 = require("@input/pen-types");
9855
9936
 
9856
9937
  // src/commands/textInsert.ts
9857
9938
  function handleInsertText(editor, param) {
@@ -10038,7 +10119,7 @@ function handleSplitBlock(editor) {
10038
10119
  if (!block) {
10039
10120
  return false;
10040
10121
  }
10041
- const newBlockId = (0, import_pen_types4.generateId)();
10122
+ const newBlockId = (0, import_pen_types5.generateId)();
10042
10123
  const recipe = buildSplitBlockRecipe({
10043
10124
  block,
10044
10125
  offset: focus.offset,
@@ -10469,12 +10550,12 @@ function getCommandRegistry(editor) {
10469
10550
  }
10470
10551
 
10471
10552
  // src/facets/a11yFacets.ts
10472
- var import_pen_types5 = require("@input/pen-types");
10553
+ var import_pen_types6 = require("@input/pen-types");
10473
10554
  function isUsableA11yLabel(value) {
10474
10555
  if (typeof value === "string") {
10475
10556
  return value.trim().length > 0;
10476
10557
  }
10477
- if (value == null || !(0, import_pen_types5.isA11yLabelledBy)(value)) {
10558
+ if (value == null || !(0, import_pen_types6.isA11yLabelledBy)(value)) {
10478
10559
  return false;
10479
10560
  }
10480
10561
  return value.labelledBy.trim().length > 0;
@@ -10812,7 +10893,7 @@ function sortExtensions(extensions) {
10812
10893
  }
10813
10894
 
10814
10895
  // src/editor/editorApiHelpers.ts
10815
- var import_pen_types6 = require("@input/pen-types");
10896
+ var import_pen_types7 = require("@input/pen-types");
10816
10897
  var import_pen_yjs4 = require("@input/pen-yjs");
10817
10898
 
10818
10899
  // src/changes/blockIndex.ts
@@ -10860,44 +10941,20 @@ function createBlockIndex(initial) {
10860
10941
  snapshot() {
10861
10942
  return current;
10862
10943
  },
10863
- apply(summary) {
10864
- current = applySummaryToSnapshot(current, summary);
10944
+ applyTextLengths(blockText) {
10945
+ for (const change of blockText) {
10946
+ const previous = current.lengthById.get(change.blockId) ?? 0;
10947
+ current.lengthById.set(
10948
+ change.blockId,
10949
+ lengthAfterSplices(previous, change.splices)
10950
+ );
10951
+ }
10865
10952
  },
10866
10953
  replace(snapshot) {
10867
10954
  current = cloneSnapshot(snapshot);
10868
10955
  }
10869
10956
  };
10870
10957
  }
10871
- function applySummaryToSnapshot(snapshot, summary) {
10872
- const lengthById = new Map(snapshot.lengthById);
10873
- const typeById = new Map(snapshot.typeById);
10874
- const childrenByParentId = cloneChildren(snapshot.childrenByParentId);
10875
- for (const change of summary.structural) {
10876
- applyStructural(change, lengthById, typeById, childrenByParentId);
10877
- }
10878
- for (const text of summary.blockText) {
10879
- const previous = lengthById.get(text.blockId) ?? 0;
10880
- lengthById.set(
10881
- text.blockId,
10882
- lengthAfterSplices(previous, text.splices)
10883
- );
10884
- }
10885
- const roots = [...childrenByParentId.get(null) ?? []];
10886
- const parentById = /* @__PURE__ */ new Map();
10887
- for (const [parentId, children] of childrenByParentId) {
10888
- for (const childId of children) {
10889
- parentById.set(childId, parentId);
10890
- }
10891
- }
10892
- return {
10893
- lengthById,
10894
- typeById,
10895
- parentById,
10896
- childrenByParentId,
10897
- order: flattenOrder(roots, childrenByParentId),
10898
- roots
10899
- };
10900
- }
10901
10958
  function lengthAfterSplices(length, splices) {
10902
10959
  let next = length;
10903
10960
  for (const splice of splices) {
@@ -10915,120 +10972,6 @@ function cloneSnapshot(snapshot) {
10915
10972
  roots: [...snapshot.roots]
10916
10973
  };
10917
10974
  }
10918
- function applyStructural(change, lengthById, typeById, childrenByParentId) {
10919
- switch (change.type) {
10920
- case "block-inserted": {
10921
- insertChild(
10922
- childrenByParentId,
10923
- change.parentId,
10924
- change.index,
10925
- change.blockId
10926
- );
10927
- if (!lengthById.has(change.blockId))
10928
- lengthById.set(change.blockId, 0);
10929
- break;
10930
- }
10931
- case "block-removed": {
10932
- removeChild(childrenByParentId, change.parentId, change.blockId);
10933
- lengthById.delete(change.blockId);
10934
- typeById.delete(change.blockId);
10935
- childrenByParentId.delete(change.blockId);
10936
- break;
10937
- }
10938
- case "block-moved": {
10939
- removeChild(
10940
- childrenByParentId,
10941
- change.fromParentId,
10942
- change.blockId
10943
- );
10944
- insertChild(
10945
- childrenByParentId,
10946
- change.toParentId,
10947
- change.toIndex,
10948
- change.blockId
10949
- );
10950
- break;
10951
- }
10952
- case "block-split": {
10953
- insertAfter(childrenByParentId, change.blockId, change.newBlockId);
10954
- const original = lengthById.get(change.blockId) ?? 0;
10955
- lengthById.set(change.blockId, Math.max(0, change.offset));
10956
- lengthById.set(
10957
- change.newBlockId,
10958
- Math.max(0, original - change.offset)
10959
- );
10960
- if (!typeById.has(change.newBlockId)) {
10961
- typeById.set(
10962
- change.newBlockId,
10963
- typeById.get(change.blockId) ?? ""
10964
- );
10965
- }
10966
- break;
10967
- }
10968
- case "blocks-merged": {
10969
- const parentId = parentOf(childrenByParentId, change.sourceBlockId);
10970
- const targetLength = lengthById.get(change.targetBlockId) ?? 0;
10971
- const sourceLength = lengthById.get(change.sourceBlockId) ?? 0;
10972
- lengthById.set(change.targetBlockId, targetLength + sourceLength);
10973
- removeChild(childrenByParentId, parentId, change.sourceBlockId);
10974
- lengthById.delete(change.sourceBlockId);
10975
- typeById.delete(change.sourceBlockId);
10976
- childrenByParentId.delete(change.sourceBlockId);
10977
- break;
10978
- }
10979
- case "block-props-changed":
10980
- case "table-changed":
10981
- case "apps-changed":
10982
- case "metadata-changed":
10983
- break;
10984
- default: {
10985
- const _exhaustive = change;
10986
- return _exhaustive;
10987
- }
10988
- }
10989
- }
10990
- function insertAfter(childrenByParentId, beforeId, newId) {
10991
- for (const [parentId, children] of childrenByParentId) {
10992
- const index = children.indexOf(beforeId);
10993
- if (index < 0) continue;
10994
- if (!children.includes(newId)) {
10995
- children.splice(index + 1, 0, newId);
10996
- }
10997
- childrenByParentId.set(parentId, children);
10998
- return;
10999
- }
11000
- insertChild(childrenByParentId, null, -1, newId);
11001
- }
11002
- function insertChild(childrenByParentId, parentId, index, blockId) {
11003
- const children = childrenByParentId.get(parentId) ?? [];
11004
- const next = children.filter((id) => id !== blockId);
11005
- const at = index < 0 || index > next.length ? next.length : index;
11006
- next.splice(at, 0, blockId);
11007
- childrenByParentId.set(parentId, next);
11008
- }
11009
- function removeChild(childrenByParentId, parentId, blockId) {
11010
- const children = childrenByParentId.get(parentId);
11011
- if (!children) {
11012
- for (const [id, list] of childrenByParentId) {
11013
- const index2 = list.indexOf(blockId);
11014
- if (index2 >= 0) {
11015
- list.splice(index2, 1);
11016
- childrenByParentId.set(id, list);
11017
- return;
11018
- }
11019
- }
11020
- return;
11021
- }
11022
- const index = children.indexOf(blockId);
11023
- if (index >= 0) children.splice(index, 1);
11024
- childrenByParentId.set(parentId, children);
11025
- }
11026
- function parentOf(childrenByParentId, blockId) {
11027
- for (const [parentId, children] of childrenByParentId) {
11028
- if (children.includes(blockId)) return parentId;
11029
- }
11030
- return null;
11031
- }
11032
10975
  function flattenOrder(roots, childrenByParentId) {
11033
10976
  const order = [];
11034
10977
  const visit = (id) => {
@@ -11060,19 +11003,19 @@ function toStringMap(value) {
11060
11003
 
11061
11004
  // src/editor/editorApiHelpers.ts
11062
11005
  var FACET_BY_SLOT_KEY = {
11063
- [import_pen_types6.FIELD_EDITOR_SLOT_KEY]: fieldEditorHostFacet,
11064
- [import_pen_types6.INPUT_RULES_ENGINE_SLOT_KEY]: inputRulesEngineFacet,
11065
- [import_pen_types6.UNDO_HISTORY_RESTORE_SLOT_KEY]: undoRestoreControllerFacet,
11066
- [import_pen_types6.UNDO_HISTORY_METADATA_CONTROLLER_SLOT_KEY]: undoMetadataControllerFacet,
11067
- [import_pen_types6.INLINE_COMPLETION_SLOT]: aiInlineCompletionFacet,
11068
- [import_pen_types6.AI_CONTROLLER_SLOT]: aiControllerFacet,
11069
- [import_pen_types6.AI_INLINE_HISTORY_SLOT]: aiInlineHistoryFacet,
11070
- [import_pen_types6.AI_REVIEW_CONTROLLER_SLOT]: aiReviewControllerFacet,
11071
- [import_pen_types6.AI_AUTOCOMPLETE_CONTROLLER_SLOT]: aiAutocompleteControllerFacet,
11072
- [import_pen_types6.AI_SUGGESTIONS_CONTROLLER_SLOT]: aiSuggestionsControllerFacet,
11073
- [import_pen_types6.SEARCH_CONTROLLER_SLOT]: searchControllerFacet,
11074
- [import_pen_types6.MULTIPLAYER_CONTROLLER_SLOT]: multiplayerControllerFacet,
11075
- [import_pen_types6.SNAPSHOTS_CONTROLLER_SLOT]: snapshotsControllerFacet,
11006
+ [import_pen_types7.FIELD_EDITOR_SLOT_KEY]: fieldEditorHostFacet,
11007
+ [import_pen_types7.INPUT_RULES_ENGINE_SLOT_KEY]: inputRulesEngineFacet,
11008
+ [import_pen_types7.UNDO_HISTORY_RESTORE_SLOT_KEY]: undoRestoreControllerFacet,
11009
+ [import_pen_types7.UNDO_HISTORY_METADATA_CONTROLLER_SLOT_KEY]: undoMetadataControllerFacet,
11010
+ [import_pen_types7.INLINE_COMPLETION_SLOT]: aiInlineCompletionFacet,
11011
+ [import_pen_types7.AI_CONTROLLER_SLOT]: aiControllerFacet,
11012
+ [import_pen_types7.AI_INLINE_HISTORY_SLOT]: aiInlineHistoryFacet,
11013
+ [import_pen_types7.AI_REVIEW_CONTROLLER_SLOT]: aiReviewControllerFacet,
11014
+ [import_pen_types7.AI_AUTOCOMPLETE_CONTROLLER_SLOT]: aiAutocompleteControllerFacet,
11015
+ [import_pen_types7.AI_SUGGESTIONS_CONTROLLER_SLOT]: aiSuggestionsControllerFacet,
11016
+ [import_pen_types7.SEARCH_CONTROLLER_SLOT]: searchControllerFacet,
11017
+ [import_pen_types7.MULTIPLAYER_CONTROLLER_SLOT]: multiplayerControllerFacet,
11018
+ [import_pen_types7.SNAPSHOTS_CONTROLLER_SLOT]: snapshotsControllerFacet,
11076
11019
  "paste:importers": clipboardFacet,
11077
11020
  "paste:assetProvider": assetProviderFacet,
11078
11021
  "undo:manager": undoManagerFacet,
@@ -11081,7 +11024,7 @@ var FACET_BY_SLOT_KEY = {
11081
11024
  "pen.messages": messagesFacet,
11082
11025
  "pen.a11yLabel": a11yLabelFacet,
11083
11026
  "delta-stream:target": streamingTargetFacet,
11084
- [import_pen_types6.ANNOUNCER_SLOT_KEY]: announcerFacet
11027
+ [import_pen_types7.ANNOUNCER_SLOT_KEY]: announcerFacet
11085
11028
  };
11086
11029
  function writeAssignedSlot(self, key, value) {
11087
11030
  self._slots.set(key, value);
@@ -11153,10 +11096,10 @@ function recordMutationGroupMetadata(editor, origin, groupId) {
11153
11096
  return;
11154
11097
  }
11155
11098
  const controller = self._slots.get(
11156
- import_pen_types6.UNDO_HISTORY_METADATA_CONTROLLER_SLOT_KEY
11099
+ import_pen_types7.UNDO_HISTORY_METADATA_CONTROLLER_SLOT_KEY
11157
11100
  );
11158
11101
  controller?.setCurrentEntryMetadata(
11159
- import_pen_types6.MUTATION_GROUP_METADATA_KEY,
11102
+ import_pen_types7.MUTATION_GROUP_METADATA_KEY,
11160
11103
  {
11161
11104
  before: null,
11162
11105
  after: createMutationGroupMetadata(origin, groupId)
@@ -11601,7 +11544,7 @@ function openEditorTextStream(editor, target, options, host) {
11601
11544
  }
11602
11545
 
11603
11546
  // src/editor/editorLifecycle.ts
11604
- var import_pen_types8 = require("@input/pen-types");
11547
+ var import_pen_types9 = require("@input/pen-types");
11605
11548
 
11606
11549
  // src/changes/install.ts
11607
11550
  var import_pen_yjs5 = require("@input/pen-yjs");
@@ -11616,7 +11559,7 @@ function affectedBlockIdsFromSummary(summary, documentOrder) {
11616
11559
  addStructuralBlockIds(ids, change);
11617
11560
  }
11618
11561
  const collected = [...ids];
11619
- if (!documentOrder || documentOrder.length === 0) {
11562
+ if (collected.length < 2 || !documentOrder || documentOrder.length === 0) {
11620
11563
  return collected;
11621
11564
  }
11622
11565
  const rank = /* @__PURE__ */ new Map();
@@ -12038,14 +11981,22 @@ function installChangeSummaries(host) {
12038
11981
  host._unsubSummary = (0, import_pen_yjs5.createSummarySource)(
12039
11982
  host._crdtDoc,
12040
11983
  (delta) => {
12041
- host._pendingSummary = buildChangeSummary(
11984
+ if (delta.blockOrderDelta.length > 0 || delta.childArrayDeltas.size > 0) {
11985
+ host._engine.notifyStructureChanged();
11986
+ }
11987
+ const summary = buildChangeSummary(
12042
11988
  delta,
12043
11989
  host._blockIndex.snapshot(),
12044
11990
  0
12045
11991
  );
12046
- host._blockIndex.replace(
12047
- createBlockIndexSnapshotFromDocument(host._doc)
12048
- );
11992
+ host._pendingSummary = summary;
11993
+ if (summary.structural.length === 0) {
11994
+ host._blockIndex.applyTextLengths(summary.blockText);
11995
+ } else {
11996
+ host._blockIndex.replace(
11997
+ createBlockIndexSnapshotFromDocument(host._doc)
11998
+ );
11999
+ }
12049
12000
  flushDeferredCRDTEvent(host);
12050
12001
  }
12051
12002
  );
@@ -12070,11 +12021,11 @@ function flushDeferredCRDTEvent(host) {
12070
12021
  var import_pen_yjs7 = require("@input/pen-yjs");
12071
12022
 
12072
12023
  // src/migrations/runMigrations.ts
12073
- var import_pen_types7 = require("@input/pen-types");
12024
+ var import_pen_types8 = require("@input/pen-types");
12074
12025
  var MIGRATION_ORIGIN = "migration";
12075
12026
  function readLedger(editor) {
12076
12027
  const value = editor.internals.doc.metadata.get(
12077
- import_pen_types7.MIGRATION_LEDGER_METADATA_KEY
12028
+ import_pen_types8.MIGRATION_LEDGER_METADATA_KEY
12078
12029
  );
12079
12030
  if (!Array.isArray(value)) {
12080
12031
  return [];
@@ -12083,7 +12034,7 @@ function readLedger(editor) {
12083
12034
  }
12084
12035
  function writeLedger(editor, ids) {
12085
12036
  const metadata = editor.internals.doc.metadata;
12086
- metadata.set(import_pen_types7.MIGRATION_LEDGER_METADATA_KEY, [...ids]);
12037
+ metadata.set(import_pen_types8.MIGRATION_LEDGER_METADATA_KEY, [...ids]);
12087
12038
  }
12088
12039
  function bindMigrationApply(editor) {
12089
12040
  const previousApply = editor.apply.bind(editor);
@@ -12444,7 +12395,7 @@ function ensureInitialParagraph(editor) {
12444
12395
  [
12445
12396
  {
12446
12397
  type: "insert-block",
12447
- blockId: (0, import_pen_types8.generateId)(),
12398
+ blockId: (0, import_pen_types9.generateId)(),
12448
12399
  blockType: "paragraph",
12449
12400
  props: {},
12450
12401
  position: "last"
@@ -12572,7 +12523,7 @@ function stampSummaryCommitId(summary, commitId) {
12572
12523
  }
12573
12524
 
12574
12525
  // src/editor/editorSelectionMutations.ts
12575
- var import_pen_types9 = require("@input/pen-types");
12526
+ var import_pen_types10 = require("@input/pen-types");
12576
12527
  function replaceEditorSelection(editor, content) {
12577
12528
  const self = editor;
12578
12529
  const sel = self._selection.getSelection();
@@ -12631,7 +12582,7 @@ function replaceEditorSelection(editor, content) {
12631
12582
  )
12632
12583
  };
12633
12584
  if (typeof content === "string") {
12634
- const newId = (0, import_pen_types9.generateId)();
12585
+ const newId = (0, import_pen_types10.generateId)();
12635
12586
  ops.push({
12636
12587
  type: "insert-block",
12637
12588
  blockId: newId,
@@ -12651,7 +12602,7 @@ function replaceEditorSelection(editor, content) {
12651
12602
  } else if (Array.isArray(content)) {
12652
12603
  let prevPosition = insertPosition;
12653
12604
  for (const block of content) {
12654
- const newId = (0, import_pen_types9.generateId)();
12605
+ const newId = (0, import_pen_types10.generateId)();
12655
12606
  ops.push({
12656
12607
  type: "insert-block",
12657
12608
  blockId: newId,
@@ -13007,7 +12958,7 @@ var EditorImpl = class {
13007
12958
  _unsubSummary = null;
13008
12959
  _blockRevisions = /* @__PURE__ */ new Map();
13009
12960
  _decorations;
13010
- _viewId = (0, import_pen_types10.generateId)();
12961
+ _viewId = (0, import_pen_types11.generateId)();
13011
12962
  _extensionLifecycle = Promise.resolve();
13012
12963
  _facetRegistry;
13013
12964
  _slotDeprecationWarned = /* @__PURE__ */ new Set();
@@ -13478,7 +13429,7 @@ function createHeadlessEditor(options = {}) {
13478
13429
  }
13479
13430
 
13480
13431
  // src/editor/inlineCompletion.ts
13481
- var import_pen_types11 = require("@input/pen-types");
13432
+ var import_pen_types12 = require("@input/pen-types");
13482
13433
  var inlineCompletionLeases = /* @__PURE__ */ new WeakMap();
13483
13434
  var InlineCompletionControllerImpl = class {
13484
13435
  constructor(_editor) {
@@ -13543,7 +13494,7 @@ var InlineCompletionControllerImpl = class {
13543
13494
  this._emit();
13544
13495
  return true;
13545
13496
  }
13546
- const blockId = (0, import_pen_types11.generateId)();
13497
+ const blockId = (0, import_pen_types12.generateId)();
13547
13498
  this._editor.apply(
13548
13499
  [
13549
13500
  {
@@ -13583,7 +13534,7 @@ var InlineCompletionControllerImpl = class {
13583
13534
  type: "block",
13584
13535
  blockId: suggestion2.blockId,
13585
13536
  attributes: {
13586
- [import_pen_types11.INLINE_COMPLETION_VISIBLE_BLOCK_ATTRIBUTE]: true
13537
+ [import_pen_types12.INLINE_COMPLETION_VISIBLE_BLOCK_ATTRIBUTE]: true
13587
13538
  }
13588
13539
  };
13589
13540
  if (suggestion2.type !== "inline") {
@@ -13654,7 +13605,7 @@ function ensureInlineCompletionController(editor) {
13654
13605
  };
13655
13606
  }
13656
13607
  const controller = new InlineCompletionControllerImpl(editor);
13657
- editor.internals.assignSlot(import_pen_types11.INLINE_COMPLETION_SLOT, controller);
13608
+ editor.internals.assignSlot(import_pen_types12.INLINE_COMPLETION_SLOT, controller);
13658
13609
  inlineCompletionLeases.set(editor, {
13659
13610
  controller,
13660
13611
  refCount: 1
@@ -13682,7 +13633,7 @@ function createInlineCompletionRelease(editor, controller) {
13682
13633
  }
13683
13634
  inlineCompletionLeases.delete(editor);
13684
13635
  if (getInlineCompletionController(editor) === controller) {
13685
- editor.internals.assignSlot(import_pen_types11.INLINE_COMPLETION_SLOT, null);
13636
+ editor.internals.assignSlot(import_pen_types12.INLINE_COMPLETION_SLOT, null);
13686
13637
  }
13687
13638
  controller.destroy();
13688
13639
  };
@@ -13815,13 +13766,13 @@ function renderSelectionTargetBlockText(editor, target, options) {
13815
13766
  }
13816
13767
 
13817
13768
  // src/importerUtils.ts
13818
- var import_pen_types12 = require("@input/pen-types");
13769
+ var import_pen_types13 = require("@input/pen-types");
13819
13770
  function blocksToOps(blocks, options) {
13820
13771
  const ops = [];
13821
13772
  let position = options?.position ?? "last";
13822
13773
  for (const block of blocks) {
13823
13774
  if (block.type.startsWith("__table")) continue;
13824
- const blockId = (0, import_pen_types12.generateId)();
13775
+ const blockId = (0, import_pen_types13.generateId)();
13825
13776
  ops.push({
13826
13777
  type: "insert-block",
13827
13778
  blockId,
@@ -14061,7 +14012,7 @@ var urlPolicyFacet = defineFacet({
14061
14012
  });
14062
14013
 
14063
14014
  // src/facets/aiEgressFacet.ts
14064
- var import_pen_types13 = require("@input/pen-types");
14015
+ var import_pen_types14 = require("@input/pen-types");
14065
14016
  var aiEgressFacet = defineFacet({
14066
14017
  name: "pen.aiEgress",
14067
14018
  combine: (inputs) => {
@@ -14120,7 +14071,7 @@ function emitInventory(editor, context) {
14120
14071
  return;
14121
14072
  }
14122
14073
  editor.internals.emit("diagnostic", {
14123
- code: import_pen_types13.AI_EGRESS_INVENTORY_CODE,
14074
+ code: import_pen_types14.AI_EGRESS_INVENTORY_CODE,
14124
14075
  level: "info",
14125
14076
  source: "ai",
14126
14077
  message: "AI request excerpt inventory",
@@ -14133,7 +14084,7 @@ function emitInventory(editor, context) {
14133
14084
  }
14134
14085
  function emitRefused(editor, context) {
14135
14086
  editor.internals.emit("diagnostic", {
14136
- code: import_pen_types13.AI_REQUEST_REFUSED_CODE,
14087
+ code: import_pen_types14.AI_REQUEST_REFUSED_CODE,
14137
14088
  level: "info",
14138
14089
  source: "ai",
14139
14090
  message: "AI request refused by pen.aiEgress",
@@ -14601,6 +14552,16 @@ var macosBindings = [
14601
14552
  key: "Alt-Delete",
14602
14553
  command: deleteForward,
14603
14554
  param: { granularity: "word" }
14555
+ },
14556
+ {
14557
+ key: "Meta-Backspace",
14558
+ command: deleteBackward,
14559
+ param: { granularity: "line" }
14560
+ },
14561
+ {
14562
+ key: "Ctrl-k",
14563
+ command: deleteForward,
14564
+ param: { granularity: "line" }
14604
14565
  }
14605
14566
  ];
14606
14567
  var windowsLinuxBindings = [
@@ -14644,7 +14605,7 @@ var defaultKeymapBindings = {
14644
14605
  };
14645
14606
 
14646
14607
  // src/i18n/messages.ts
14647
- var import_pen_types14 = require("@input/pen-types");
14608
+ var import_pen_types15 = require("@input/pen-types");
14648
14609
  function interpolateMessage(template, params) {
14649
14610
  if (!params) {
14650
14611
  return template;
@@ -14661,21 +14622,21 @@ function interpolateMessage(template, params) {
14661
14622
  );
14662
14623
  }
14663
14624
  function resolveMessage(catalog, key, ...args) {
14664
- const raw = catalog[key] ?? import_pen_types14.DEFAULT_MESSAGE_CATALOG[key];
14625
+ const raw = catalog[key] ?? import_pen_types15.DEFAULT_MESSAGE_CATALOG[key];
14665
14626
  if (raw == null) {
14666
14627
  return "";
14667
14628
  }
14668
- if ((0, import_pen_types14.isPluralMessage)(raw)) {
14629
+ if ((0, import_pen_types15.isPluralMessage)(raw)) {
14669
14630
  return interpolateMessage(raw.other, args[0]);
14670
14631
  }
14671
14632
  return interpolateMessage(raw, args[0]);
14672
14633
  }
14673
14634
 
14674
14635
  // src/editor/toolExecution.ts
14675
- var import_pen_types15 = require("@input/pen-types");
14636
+ var import_pen_types16 = require("@input/pen-types");
14676
14637
  async function collectToolExecutionOutput(result, onPart) {
14677
14638
  const resolved = await result;
14678
- if (!(0, import_pen_types15.isAsyncIterable)(resolved)) {
14639
+ if (!(0, import_pen_types16.isAsyncIterable)(resolved)) {
14679
14640
  return resolved;
14680
14641
  }
14681
14642
  const parts = [];
@@ -14687,7 +14648,7 @@ async function collectToolExecutionOutput(result, onPart) {
14687
14648
  }
14688
14649
 
14689
14650
  // src/i18n/resolveEditorMessage.ts
14690
- var import_pen_types16 = require("@input/pen-types");
14651
+ var import_pen_types17 = require("@input/pen-types");
14691
14652
 
14692
14653
  // src/i18n/formatters.ts
14693
14654
  function formatterKey(locale, options) {
@@ -14746,7 +14707,7 @@ function resolveEditorMessage(editor, key, ...args) {
14746
14707
  return interpolateMessage(selectTemplate(value, locale, params), params);
14747
14708
  }
14748
14709
  function selectTemplate(value, locale, params) {
14749
- if (!(0, import_pen_types16.isPluralMessage)(value)) {
14710
+ if (!(0, import_pen_types17.isPluralMessage)(value)) {
14750
14711
  return value;
14751
14712
  }
14752
14713
  const count = params?.count;
@@ -14774,7 +14735,7 @@ function emitMissingOnce(editor, key) {
14774
14735
  }
14775
14736
 
14776
14737
  // src/a11y/resolveEditorA11yLabel.ts
14777
- var import_pen_types17 = require("@input/pen-types");
14738
+ var import_pen_types18 = require("@input/pen-types");
14778
14739
  var A11Y_MISSING_LABEL_CODE = "a11y-missing-label";
14779
14740
  var missingLabelWarned = /* @__PURE__ */ new WeakSet();
14780
14741
  function resolveEditorA11yLabel(editor) {
@@ -14782,7 +14743,7 @@ function resolveEditorA11yLabel(editor) {
14782
14743
  if (typeof value === "string") {
14783
14744
  return { "aria-label": value };
14784
14745
  }
14785
- if (value != null && (0, import_pen_types17.isA11yLabelledBy)(value)) {
14746
+ if (value != null && (0, import_pen_types18.isA11yLabelledBy)(value)) {
14786
14747
  return { "aria-labelledby": value.labelledBy };
14787
14748
  }
14788
14749
  warnMissingA11yLabel(editor);
@@ -14808,7 +14769,7 @@ function warnMissingA11yLabel(editor) {
14808
14769
  }
14809
14770
 
14810
14771
  // src/a11y/announceEditorA11y.ts
14811
- var import_pen_types18 = require("@input/pen-types");
14772
+ var import_pen_types19 = require("@input/pen-types");
14812
14773
  function announceEditorA11y(editor, key, ...args) {
14813
14774
  const announcer = editor.facet(announcerFacet) ?? null;
14814
14775
  if (!announcer) {
@@ -14827,7 +14788,7 @@ function announceEditorA11y(editor, key, ...args) {
14827
14788
  }
14828
14789
  function resolveA11yBlockTypeLabel(editor, type) {
14829
14790
  const key = `pen.schema.${type}.title`;
14830
- if ((0, import_pen_types18.isMessageKey)(key)) {
14791
+ if ((0, import_pen_types19.isMessageKey)(key)) {
14831
14792
  const label = resolveEditorMessage(editor, key);
14832
14793
  if (label.length > 0) {
14833
14794
  return label;
@@ -14880,7 +14841,7 @@ function warnMissingSchemaA11y(editor, type) {
14880
14841
  }
14881
14842
 
14882
14843
  // src/i18n/pseudoLocale.ts
14883
- var import_pen_types19 = require("@input/pen-types");
14844
+ var import_pen_types20 = require("@input/pen-types");
14884
14845
  var PSEUDO_LOCALE_OPEN = "[[";
14885
14846
  var PSEUDO_LOCALE_CLOSE = " \xB7\xB7\xB7]]";
14886
14847
  function toPseudoLocaleText(text) {
@@ -14890,7 +14851,7 @@ function toPseudoLocaleText(text) {
14890
14851
  return `${PSEUDO_LOCALE_OPEN}${text}${PSEUDO_LOCALE_CLOSE}`;
14891
14852
  }
14892
14853
  function toPseudoLocaleValue(value) {
14893
- if (!(0, import_pen_types19.isPluralMessage)(value)) {
14854
+ if (!(0, import_pen_types20.isPluralMessage)(value)) {
14894
14855
  return toPseudoLocaleText(value);
14895
14856
  }
14896
14857
  const next = {
@@ -14903,7 +14864,7 @@ function toPseudoLocaleValue(value) {
14903
14864
  }
14904
14865
  return next;
14905
14866
  }
14906
- function createPseudoLocaleCatalog(catalog = import_pen_types19.DEFAULT_MESSAGE_CATALOG) {
14867
+ function createPseudoLocaleCatalog(catalog = import_pen_types20.DEFAULT_MESSAGE_CATALOG) {
14907
14868
  const next = {};
14908
14869
  for (const key of Object.keys(catalog)) {
14909
14870
  next[key] = toPseudoLocaleValue(catalog[key]);
@@ -15085,6 +15046,8 @@ function mapOffsetThroughSplices(splices, offset, assoc) {
15085
15046
  interpolateMessage,
15086
15047
  isBlockSelected,
15087
15048
  isCollapsed,
15049
+ isContainerBlock,
15050
+ isContainerBlockType,
15088
15051
  isContinuousTextFlowCapability,
15089
15052
  isMultiBlock,
15090
15053
  isPseudoLocaleText,
@@ -15101,6 +15064,7 @@ function mapOffsetThroughSplices(splices, offset, assoc) {
15101
15064
  nextGraphemeBoundary,
15102
15065
  nextWordBoundary,
15103
15066
  normalizePendingBlocksForImport,
15067
+ orderSlashMenuItemsByGroup,
15104
15068
  outdent,
15105
15069
  previousGraphemeBoundary,
15106
15070
  previousWordBoundary,
@@ -15143,8 +15107,10 @@ function mapOffsetThroughSplices(splices, offset, assoc) {
15143
15107
  shouldAllowFlowInsertionInSlashMenu,
15144
15108
  shouldExposeBlockInTooling,
15145
15109
  shouldForceBlockScopedSelectAll,
15110
+ shouldRenderContainerChildren,
15146
15111
  shouldShowBlockInDefaultMenus,
15147
15112
  singleController,
15113
+ slashMenuGroupOf,
15148
15114
  snapToNormalPosition,
15149
15115
  snapshotsControllerFacet,
15150
15116
  sortDeltaAttributes,