@adea-ai/ui 0.66.0 → 0.67.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -343,6 +343,11 @@ imported into this model.
343
343
 
344
344
  ### Host pane presentation hooks
345
345
 
346
+ Controlled split ratios survive host visibility changes and disposal. Corvu panel
347
+ registration and unregistration callbacks with incomplete sizes, and callbacks
348
+ from detached or hidden roots, do not become host resize requests. Real pointer
349
+ and keyboard resizing still flows through the same constrained callback.
350
+
346
351
  `SplitLayout` can keep its default pane header while allowing a host to supply
347
352
  inline visible content with `renderPaneLabel`, opt pane regions into keyboard
348
353
  Tab navigation with `paneTabIndex={0}`, and provide a domain-specific splitter
@@ -368,6 +373,15 @@ imports and a 3 KiB gzip model budget (measured baseline: 2,455 bytes). This is
368
373
  model-subpath evidence; it does not waive UI #16's package attribution/conditional
369
374
  export corrections or the separate root compatibility gate.
370
375
 
376
+ `bun run check:packed-paste-model` installs the actual archive with peer and
377
+ optional packages omitted. It verifies the direct
378
+ `@adea-ai/ui/components/conversation/paste-tokens` entry in native Node and the
379
+ Solid source condition, a strict clean TypeScript consumer without ambient types,
380
+ round-trip/range/pruning and invalid-metadata behavior, and exact packed
381
+ LICENSE/NOTICE fidelity. The pure compiled module retains zero runtime imports
382
+ and stays within a 3 KiB gzip budget. This gate runs in local verification, CI
383
+ and publication; textarea editing and production adoption remain separate gates.
384
+
371
385
  ### Controlled appearance editor
372
386
 
373
387
  `AppearanceEditor` and `AppearancePopover` retain the accepted Zeron-derived
@@ -417,3 +431,15 @@ not just the editor primitive.
417
431
  Local packed interaction gates require `bunx playwright install chromium webkit`
418
432
  after dependency installation. On Linux, use `--with-deps` when the required
419
433
  system libraries are absent. All automation runs headless with disposable profiles.
434
+
435
+ ## Paste-token model (issue #532 selected unit)
436
+
437
+ `@adea-ai/ui/components/conversation` also exports the pure paste-token model:
438
+ `PasteBlock`, `isPasteBlock`, `countLines`, `shouldCollapse`, `nextSeq`,
439
+ `formatToken`, `findTokenRanges`, `tokenRangeAt`, `pruneBlocks`, `expandAll`,
440
+ `recollapsePastes`, `remapCarriedBlocks`, `stripTrailingBlankLines`, and the
441
+ threshold and marker constants. Hosts provide stable, bounded ASCII block IDs and own
442
+ draft state, persistence, message reconciliation and editor behavior. The model
443
+ does not read storage or the clipboard, upload files, edit a textarea, or
444
+ provide undo/history, previews or chips. Its selected source and Apache-2.0
445
+ attribution are recorded in the issue #532 entry in `NOTICE`.
package/dist/NOTICE CHANGED
@@ -267,3 +267,27 @@ pane-title gesture, replacing plaintext leaf IDs and string casts with typed
267
267
  intent, an instance-local active drag payload, and cancellation/removal checks.
268
268
  Header action composition injects application keyboard controls without owning
269
269
  shortcuts or domain transitions. No new upstream source or license is introduced.
270
+ ## Paste-token model translated from KiroCrew (issue #532)
271
+
272
+ `packages/ui/src/components/conversation/paste-tokens.ts` translates the pure
273
+ block and text transformations from `website/src/utils/pasteTokens.ts`, plus
274
+ the trailing-blank-line policy from `website/src/components/composerPastePolicy.ts`,
275
+ at KiroCrew revision `283e136c0f902e965a535a7c9548c57c7504fed0`.
276
+
277
+ Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
278
+ This product includes software developed at Amazon.com, Inc.
279
+ (https://www.amazon.com/). Licensed under the Apache License, Version 2.0.
280
+
281
+ Retained: the three-line/200-character collapse thresholds; canonical marker
282
+ formatting and ranges; monotonic sequence allocation and collision remapping;
283
+ token pruning, expansion and content-based re-collapse, including the
284
+ trailing-whitespace fallback; and the linear trailing-blank-line scan. Bun unit
285
+ cases adapt the pure expectations from `website/src/test/pasteTokens.test.ts` and
286
+ the trailing-text policy from `website/src/test/ChatInput.paste.test.tsx`.
287
+
288
+ The host supplies stable block IDs. Invalid IDs/sequences, duplicate identities,
289
+ ambiguous sequence mappings and noncanonical or line-mismatched markers are
290
+ refused. React, Lexical, browser clipboard/File handling, localStorage side-table
291
+ recovery, backend message reconciliation, uploads, textarea editing, previews,
292
+ chips, undo/history and submit/persistence authority are not included. This
293
+ selected model is not rich editing, complete Chat, or application adoption.
@@ -5,4 +5,5 @@ export { ConversationSurface, type ConversationSurfaceProps } from './conversati
5
5
  export { ComposerAttachmentButton, ComposerHint, MessageComposer, type MessageComposerProps, } from './message-composer';
6
6
  export { MessageBody, MessageDayDivider, MessageGroup, MessageRow, type MessageRowProps, } from './message-row';
7
7
  export { AttachmentCard, ThreadPanel, type AttachmentCardProps, type ThreadPanelProps, } from './thread-panel';
8
+ export { countLines, expandAll, findTokenRanges, formatToken, isPasteBlock, nextSeq, pruneBlocks, recollapsePastes, remapCarriedBlocks, shouldCollapse, stripTrailingBlankLines, tokenRangeAt, PASTE_THRESHOLD_CHARS, PASTE_THRESHOLD_LINES, PASTE_TOKEN_REGEX, type PasteBlock, } from './paste-tokens';
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,KAAK,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAChG,OAAO,EAAE,cAAc,EAAE,KAAK,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AAChG,OAAO,EACL,kBAAkB,EAClB,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,GAC7B,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAAE,mBAAmB,EAAE,KAAK,wBAAwB,EAAE,MAAM,wBAAwB,CAAA;AAC3F,OAAO,EACL,wBAAwB,EACxB,YAAY,EACZ,eAAe,EACf,KAAK,oBAAoB,GAC1B,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,YAAY,EACZ,UAAU,EACV,KAAK,eAAe,GACrB,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,cAAc,EACd,WAAW,EACX,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,GACtB,MAAM,gBAAgB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,KAAK,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAChG,OAAO,EAAE,cAAc,EAAE,KAAK,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AAChG,OAAO,EACL,kBAAkB,EAClB,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,GAC7B,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAAE,mBAAmB,EAAE,KAAK,wBAAwB,EAAE,MAAM,wBAAwB,CAAA;AAC3F,OAAO,EACL,wBAAwB,EACxB,YAAY,EACZ,eAAe,EACf,KAAK,oBAAoB,GAC1B,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,YAAY,EACZ,UAAU,EACV,KAAK,eAAe,GACrB,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,cAAc,EACd,WAAW,EACX,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,GACtB,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EACL,UAAU,EACV,SAAS,EACT,eAAe,EACf,WAAW,EACX,YAAY,EACZ,OAAO,EACP,WAAW,EACX,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,uBAAuB,EACvB,YAAY,EACZ,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,KAAK,UAAU,GAChB,MAAM,gBAAgB,CAAA"}
@@ -5,4 +5,5 @@ import { ConversationSurface } from "./conversation-surface.js";
5
5
  import { ComposerAttachmentButton, ComposerHint, MessageComposer } from "./message-composer.js";
6
6
  import { MessageBody, MessageDayDivider, MessageGroup, MessageRow } from "./message-row.js";
7
7
  import { AttachmentCard, ThreadPanel } from "./thread-panel.js";
8
- export { AttachmentCard, BusySendButton, ChatComposer, ComposerAttachmentButton, ComposerHint, ConversationAvatar, ConversationSurface, MessageBody, MessageComposer, MessageDayDivider, MessageGroup, MessageRow, ThreadPanel };
8
+ import { PASTE_THRESHOLD_CHARS, PASTE_THRESHOLD_LINES, PASTE_TOKEN_REGEX, countLines, expandAll, findTokenRanges, formatToken, isPasteBlock, nextSeq, pruneBlocks, recollapsePastes, remapCarriedBlocks, shouldCollapse, stripTrailingBlankLines, tokenRangeAt } from "./paste-tokens.js";
9
+ export { AttachmentCard, BusySendButton, ChatComposer, ComposerAttachmentButton, ComposerHint, ConversationAvatar, ConversationSurface, MessageBody, MessageComposer, MessageDayDivider, MessageGroup, MessageRow, PASTE_THRESHOLD_CHARS, PASTE_THRESHOLD_LINES, PASTE_TOKEN_REGEX, ThreadPanel, countLines, expandAll, findTokenRanges, formatToken, isPasteBlock, nextSeq, pruneBlocks, recollapsePastes, remapCarriedBlocks, shouldCollapse, stripTrailingBlankLines, tokenRangeAt };
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Pure paste-token transformations translated and hardened from KiroCrew's
3
+ * `website/src/utils/pasteTokens.ts` at revision
4
+ * `283e136c0f902e965a535a7c9548c57c7504fed0` (Apache-2.0). See the #532 entry
5
+ * in the repository NOTICE. Paste identity is supplied by the host; this module
6
+ * does not access storage, clipboard APIs, message services, or editor state.
7
+ */
8
+ /** A collapsed paste block stored alongside input or a message. */
9
+ export interface PasteBlock {
10
+ /** A stable host-provided ASCII identifier; never included in visible token text. */
11
+ id: string;
12
+ /** Positive safe integer, unique among blocks in the same text value. */
13
+ seq: number;
14
+ /** Positive safe integer displayed in the token. */
15
+ lines: number;
16
+ /** Original pasted text, retained verbatim. */
17
+ content: string;
18
+ }
19
+ export declare const PASTE_THRESHOLD_LINES = 3;
20
+ export declare const PASTE_THRESHOLD_CHARS = 200;
21
+ /** Canonical token pattern. Internal scans always use a fresh RegExp instance. */
22
+ export declare const PASTE_TOKEN_REGEX: RegExp;
23
+ /** Check data received from a host before using it as a paste-token block. */
24
+ export declare function isPasteBlock(value: unknown): value is PasteBlock;
25
+ export declare function formatToken(block: PasteBlock): string;
26
+ export declare function shouldCollapse(text: string): boolean;
27
+ export declare function countLines(text: string): number;
28
+ /** Next sequence for a new paste = max existing + 1, starting at 1. */
29
+ export declare function nextSeq(blocks: readonly PasteBlock[]): number;
30
+ /**
31
+ * Re-sequence `carried` blocks whose sequence is already taken by `used`, and
32
+ * rewrite their markers in one right-to-left pass. Carried block IDs and
33
+ * sequences must be unique so a visible marker always has one backing block.
34
+ * `used` is mutated to include the assigned sequences.
35
+ */
36
+ export declare function remapCarriedBlocks(text: string, carried: readonly PasteBlock[], used: Set<number>): {
37
+ text: string;
38
+ blocks: PasteBlock[];
39
+ };
40
+ /** Ranges for canonical tokens whose sequence and line count match one block. */
41
+ export declare function findTokenRanges(text: string, blocks: readonly PasteBlock[]): Array<{
42
+ start: number;
43
+ end: number;
44
+ block: PasteBlock;
45
+ }>;
46
+ export declare function tokenRangeAt(text: string, blocks: readonly PasteBlock[], caret: number): {
47
+ start: number;
48
+ end: number;
49
+ block: PasteBlock;
50
+ } | null;
51
+ export declare function pruneBlocks(text: string, blocks: PasteBlock[]): PasteBlock[];
52
+ export declare function expandAll(text: string, blocks: readonly PasteBlock[]): string;
53
+ /** Inverse of `expandAll`: replace each first non-overlapping verbatim block. */
54
+ export declare function recollapsePastes(content: string, blocks: readonly PasteBlock[]): string;
55
+ /** Strip a trailing whitespace run only when that run contains a newline. */
56
+ export declare function stripTrailingBlankLines(value: string): string;
57
+ //# sourceMappingURL=paste-tokens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paste-tokens.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/paste-tokens.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,mEAAmE;AACnE,MAAM,WAAW,UAAU;IACzB,qFAAqF;IACrF,EAAE,EAAE,MAAM,CAAA;IACV,yEAAyE;IACzE,GAAG,EAAE,MAAM,CAAA;IACX,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAA;IACb,+CAA+C;IAC/C,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,eAAO,MAAM,qBAAqB,IAAI,CAAA;AACtC,eAAO,MAAM,qBAAqB,MAAM,CAAA;AAMxC,kFAAkF;AAClF,eAAO,MAAM,iBAAiB,QAAsC,CAAA;AAMpE,8EAA8E;AAC9E,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,CAUhE;AAaD,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAGrD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGpD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG/C;AAED,uEAAuE;AACvE,wBAAgB,OAAO,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,GAAG,MAAM,CAO7D;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,SAAS,UAAU,EAAE,EAC9B,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,GAChB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,UAAU,EAAE,CAAA;CAAE,CAiDxC;AAED,iFAAiF;AACjF,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,SAAS,UAAU,EAAE,GAC5B,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAE,CAAC,CAkB1D;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,SAAS,UAAU,EAAE,EAC7B,KAAK,EAAE,MAAM,GACZ;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAE,GAAG,IAAI,CAM1D;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,UAAU,EAAE,CAQ5E;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,UAAU,EAAE,GAAG,MAAM,CAU7E;AAED,iFAAiF;AACjF,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,UAAU,EAAE,GAAG,MAAM,CAgDvF;AAED,6EAA6E;AAC7E,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAiB7D"}
@@ -0,0 +1,216 @@
1
+ //#region src/components/conversation/paste-tokens.ts
2
+ var PASTE_THRESHOLD_LINES = 3;
3
+ var PASTE_THRESHOLD_CHARS = 200;
4
+ var PASTE_ID_PATTERN = /^[A-Za-z0-9._:-]{1,128}$/;
5
+ var MAX_SAFE_SEQUENCE_TEXT_LENGTH = String(Number.MAX_SAFE_INTEGER).length;
6
+ var PASTE_TOKEN_SOURCE = String.raw`\[ Paste #([1-9]\d{0,${MAX_SAFE_SEQUENCE_TEXT_LENGTH - 1}}) · ([1-9]\d{0,${MAX_SAFE_SEQUENCE_TEXT_LENGTH - 1}}) lines \]`;
7
+ /** Canonical token pattern. Internal scans always use a fresh RegExp instance. */
8
+ var PASTE_TOKEN_REGEX = new RegExp(PASTE_TOKEN_SOURCE, "g");
9
+ function isPositiveSafeInteger(value) {
10
+ return Number.isSafeInteger(value) && value > 0;
11
+ }
12
+ /** Check data received from a host before using it as a paste-token block. */
13
+ function isPasteBlock(value) {
14
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
15
+ const candidate = value;
16
+ return typeof candidate.id === "string" && PASTE_ID_PATTERN.test(candidate.id) && isPositiveSafeInteger(candidate.seq) && isPositiveSafeInteger(candidate.lines) && typeof candidate.content === "string";
17
+ }
18
+ function unambiguousBlocks(blocks) {
19
+ const valid = blocks.filter(isPasteBlock);
20
+ const seqCounts = /* @__PURE__ */ new Map();
21
+ const idCounts = /* @__PURE__ */ new Map();
22
+ for (const block of valid) {
23
+ seqCounts.set(block.seq, (seqCounts.get(block.seq) ?? 0) + 1);
24
+ idCounts.set(block.id, (idCounts.get(block.id) ?? 0) + 1);
25
+ }
26
+ return valid.filter((block) => seqCounts.get(block.seq) === 1 && idCounts.get(block.id) === 1);
27
+ }
28
+ function formatToken(block) {
29
+ if (!isPasteBlock(block)) throw new TypeError("Cannot format an invalid paste block");
30
+ return `[ Paste #${block.seq} · ${block.lines} lines ]`;
31
+ }
32
+ function shouldCollapse(text) {
33
+ if (!text) return false;
34
+ return countLines(text) >= 3 || text.length >= 200;
35
+ }
36
+ function countLines(text) {
37
+ if (!text) return 0;
38
+ return text.split("\n").length;
39
+ }
40
+ /** Next sequence for a new paste = max existing + 1, starting at 1. */
41
+ function nextSeq(blocks) {
42
+ let max = 0;
43
+ for (const block of blocks) if (isPasteBlock(block) && block.seq > max) max = block.seq;
44
+ if (max === Number.MAX_SAFE_INTEGER) throw new RangeError("Paste sequence space is exhausted");
45
+ return max + 1;
46
+ }
47
+ /**
48
+ * Re-sequence `carried` blocks whose sequence is already taken by `used`, and
49
+ * rewrite their markers in one right-to-left pass. Carried block IDs and
50
+ * sequences must be unique so a visible marker always has one backing block.
51
+ * `used` is mutated to include the assigned sequences.
52
+ */
53
+ function remapCarriedBlocks(text, carried, used) {
54
+ const seenSeqs = /* @__PURE__ */ new Set();
55
+ const seenIds = /* @__PURE__ */ new Set();
56
+ for (const block of carried) {
57
+ if (!isPasteBlock(block)) throw new TypeError("Cannot remap an invalid paste block");
58
+ if (seenSeqs.has(block.seq) || seenIds.has(block.id)) throw new TypeError("Carried paste block IDs and sequences must be unique");
59
+ seenSeqs.add(block.seq);
60
+ seenIds.add(block.id);
61
+ }
62
+ let maxUsed = 0;
63
+ for (const value of used) if (isPositiveSafeInteger(value) && value > maxUsed) maxUsed = value;
64
+ let free = maxUsed < Number.MAX_SAFE_INTEGER ? maxUsed + 1 : 1;
65
+ const allocateFree = () => {
66
+ while (used.has(free)) free = free < Number.MAX_SAFE_INTEGER ? free + 1 : 1;
67
+ const assigned = free;
68
+ used.add(assigned);
69
+ free = assigned < Number.MAX_SAFE_INTEGER ? assigned + 1 : 1;
70
+ return assigned;
71
+ };
72
+ const remap = /* @__PURE__ */ new Map();
73
+ const blocks = carried.map((block) => {
74
+ if (!used.has(block.seq)) {
75
+ used.add(block.seq);
76
+ return block;
77
+ }
78
+ const seq = allocateFree();
79
+ remap.set(block.seq, seq);
80
+ return {
81
+ ...block,
82
+ seq
83
+ };
84
+ });
85
+ if (!remap.size) return {
86
+ text,
87
+ blocks
88
+ };
89
+ let out = text;
90
+ const ranges = findTokenRanges(text, carried);
91
+ for (let index = ranges.length - 1; index >= 0; index -= 1) {
92
+ const { start, end, block } = ranges[index];
93
+ const mapped = remap.get(block.seq);
94
+ if (mapped === void 0) continue;
95
+ out = out.slice(0, start) + formatToken({
96
+ ...block,
97
+ seq: mapped
98
+ }) + out.slice(end);
99
+ }
100
+ return {
101
+ text: out,
102
+ blocks
103
+ };
104
+ }
105
+ /** Ranges for canonical tokens whose sequence and line count match one block. */
106
+ function findTokenRanges(text, blocks) {
107
+ if (!text || !blocks.length) return [];
108
+ const bySeq = new Map(unambiguousBlocks(blocks).map((block) => [block.seq, block]));
109
+ if (!bySeq.size) return [];
110
+ const tokenRegex = new RegExp(PASTE_TOKEN_SOURCE, "g");
111
+ const ranges = [];
112
+ let match;
113
+ while ((match = tokenRegex.exec(text)) !== null) {
114
+ const seq = Number(match[1]);
115
+ const lines = Number(match[2]);
116
+ if (!isPositiveSafeInteger(seq) || !isPositiveSafeInteger(lines)) continue;
117
+ const block = bySeq.get(seq);
118
+ if (block && block.lines === lines) ranges.push({
119
+ start: match.index,
120
+ end: match.index + match[0].length,
121
+ block
122
+ });
123
+ }
124
+ return ranges;
125
+ }
126
+ function tokenRangeAt(text, blocks, caret) {
127
+ if (!Number.isSafeInteger(caret) || caret < 0 || caret > text.length) return null;
128
+ for (const range of findTokenRanges(text, blocks)) if (caret >= range.start && caret <= range.end) return range;
129
+ return null;
130
+ }
131
+ function pruneBlocks(text, blocks) {
132
+ if (!blocks.length) return blocks;
133
+ const usable = unambiguousBlocks(blocks);
134
+ const survivors = new Set(findTokenRanges(text, usable).map((range) => range.block.id));
135
+ const next = usable.filter((block) => survivors.has(block.id));
136
+ return next.length === blocks.length && next.every((block, index) => block === blocks[index]) ? blocks : next;
137
+ }
138
+ function expandAll(text, blocks) {
139
+ if (!text || !blocks.length) return text;
140
+ const ranges = findTokenRanges(text, blocks);
141
+ if (!ranges.length) return text;
142
+ let out = text;
143
+ for (let index = ranges.length - 1; index >= 0; index -= 1) {
144
+ const range = ranges[index];
145
+ out = out.slice(0, range.start) + range.block.content + out.slice(range.end);
146
+ }
147
+ return out;
148
+ }
149
+ /** Inverse of `expandAll`: replace each first non-overlapping verbatim block. */
150
+ function recollapsePastes(content, blocks) {
151
+ if (!content || !blocks.length) return content;
152
+ const hits = [];
153
+ const claimed = [];
154
+ const firstUnclaimed = (needle) => {
155
+ if (!needle) return -1;
156
+ let from = 0;
157
+ while (from <= content.length) {
158
+ const index = content.indexOf(needle, from);
159
+ if (index < 0) return -1;
160
+ if (!claimed.some(([start, end]) => index < end && index + needle.length > start)) return index;
161
+ from = index + 1;
162
+ }
163
+ return -1;
164
+ };
165
+ for (const block of unambiguousBlocks(blocks)) {
166
+ if (!block.content) continue;
167
+ const trimmed = block.content.trimEnd();
168
+ let needle = block.content;
169
+ let index = firstUnclaimed(needle);
170
+ if (index < 0 && trimmed && trimmed !== block.content) {
171
+ needle = trimmed;
172
+ index = firstUnclaimed(needle);
173
+ }
174
+ if (index < 0) continue;
175
+ const end = index + needle.length;
176
+ hits.push({
177
+ start: index,
178
+ end,
179
+ block
180
+ });
181
+ claimed.push([index, end]);
182
+ }
183
+ if (!hits.length) return content;
184
+ hits.sort((left, right) => left.start - right.start);
185
+ let out = "";
186
+ let position = 0;
187
+ for (const hit of hits) {
188
+ if (hit.start < position) continue;
189
+ out += content.slice(position, hit.start) + formatToken(hit.block);
190
+ position = hit.end;
191
+ }
192
+ return out + content.slice(position);
193
+ }
194
+ /** Strip a trailing whitespace run only when that run contains a newline. */
195
+ function stripTrailingBlankLines(value) {
196
+ let index = value.length - 1;
197
+ let sawNewline = false;
198
+ while (index >= 0) {
199
+ const code = value.charCodeAt(index);
200
+ if (code === 10 || code === 13) {
201
+ sawNewline = true;
202
+ index -= 1;
203
+ continue;
204
+ }
205
+ if (code === 32 || code === 9) {
206
+ index -= 1;
207
+ continue;
208
+ }
209
+ break;
210
+ }
211
+ return sawNewline ? value.slice(0, index + 1) : value;
212
+ }
213
+ //#endregion
214
+ export { PASTE_THRESHOLD_CHARS, PASTE_THRESHOLD_LINES, PASTE_TOKEN_REGEX, countLines, expandAll, findTokenRanges, formatToken, isPasteBlock, nextSeq, pruneBlocks, recollapsePastes, remapCarriedBlocks, shouldCollapse, stripTrailingBlankLines, tokenRangeAt };
215
+
216
+ //# sourceMappingURL=paste-tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paste-tokens.js","names":[],"sources":["../../../src/components/conversation/paste-tokens.ts"],"sourcesContent":["/**\n * Pure paste-token transformations translated and hardened from KiroCrew's\n * `website/src/utils/pasteTokens.ts` at revision\n * `283e136c0f902e965a535a7c9548c57c7504fed0` (Apache-2.0). See the #532 entry\n * in the repository NOTICE. Paste identity is supplied by the host; this module\n * does not access storage, clipboard APIs, message services, or editor state.\n */\n\n/** A collapsed paste block stored alongside input or a message. */\nexport interface PasteBlock {\n /** A stable host-provided ASCII identifier; never included in visible token text. */\n id: string\n /** Positive safe integer, unique among blocks in the same text value. */\n seq: number\n /** Positive safe integer displayed in the token. */\n lines: number\n /** Original pasted text, retained verbatim. */\n content: string\n}\n\nexport const PASTE_THRESHOLD_LINES = 3\nexport const PASTE_THRESHOLD_CHARS = 200\n\nconst PASTE_ID_PATTERN = /^[A-Za-z0-9._:-]{1,128}$/\nconst MAX_SAFE_SEQUENCE_TEXT_LENGTH = String(Number.MAX_SAFE_INTEGER).length\nconst PASTE_TOKEN_SOURCE = String.raw`\\[ Paste #([1-9]\\d{0,${MAX_SAFE_SEQUENCE_TEXT_LENGTH - 1}}) · ([1-9]\\d{0,${MAX_SAFE_SEQUENCE_TEXT_LENGTH - 1}}) lines \\]`\n\n/** Canonical token pattern. Internal scans always use a fresh RegExp instance. */\nexport const PASTE_TOKEN_REGEX = new RegExp(PASTE_TOKEN_SOURCE, 'g')\n\nfunction isPositiveSafeInteger(value: unknown): value is number {\n return Number.isSafeInteger(value) && (value as number) > 0\n}\n\n/** Check data received from a host before using it as a paste-token block. */\nexport function isPasteBlock(value: unknown): value is PasteBlock {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false\n const candidate = value as Record<string, unknown>\n return (\n typeof candidate.id === 'string' &&\n PASTE_ID_PATTERN.test(candidate.id) &&\n isPositiveSafeInteger(candidate.seq) &&\n isPositiveSafeInteger(candidate.lines) &&\n typeof candidate.content === 'string'\n )\n}\n\nfunction unambiguousBlocks(blocks: readonly PasteBlock[]): PasteBlock[] {\n const valid = blocks.filter(isPasteBlock)\n const seqCounts = new Map<number, number>()\n const idCounts = new Map<string, number>()\n for (const block of valid) {\n seqCounts.set(block.seq, (seqCounts.get(block.seq) ?? 0) + 1)\n idCounts.set(block.id, (idCounts.get(block.id) ?? 0) + 1)\n }\n return valid.filter((block) => seqCounts.get(block.seq) === 1 && idCounts.get(block.id) === 1)\n}\n\nexport function formatToken(block: PasteBlock): string {\n if (!isPasteBlock(block)) throw new TypeError('Cannot format an invalid paste block')\n return `[ Paste #${block.seq} · ${block.lines} lines ]`\n}\n\nexport function shouldCollapse(text: string): boolean {\n if (!text) return false\n return countLines(text) >= PASTE_THRESHOLD_LINES || text.length >= PASTE_THRESHOLD_CHARS\n}\n\nexport function countLines(text: string): number {\n if (!text) return 0\n return text.split('\\n').length\n}\n\n/** Next sequence for a new paste = max existing + 1, starting at 1. */\nexport function nextSeq(blocks: readonly PasteBlock[]): number {\n let max = 0\n for (const block of blocks) {\n if (isPasteBlock(block) && block.seq > max) max = block.seq\n }\n if (max === Number.MAX_SAFE_INTEGER) throw new RangeError('Paste sequence space is exhausted')\n return max + 1\n}\n\n/**\n * Re-sequence `carried` blocks whose sequence is already taken by `used`, and\n * rewrite their markers in one right-to-left pass. Carried block IDs and\n * sequences must be unique so a visible marker always has one backing block.\n * `used` is mutated to include the assigned sequences.\n */\nexport function remapCarriedBlocks(\n text: string,\n carried: readonly PasteBlock[],\n used: Set<number>\n): { text: string; blocks: PasteBlock[] } {\n const seenSeqs = new Set<number>()\n const seenIds = new Set<string>()\n for (const block of carried) {\n if (!isPasteBlock(block)) throw new TypeError('Cannot remap an invalid paste block')\n if (seenSeqs.has(block.seq) || seenIds.has(block.id)) {\n throw new TypeError('Carried paste block IDs and sequences must be unique')\n }\n seenSeqs.add(block.seq)\n seenIds.add(block.id)\n }\n\n let maxUsed = 0\n for (const value of used) {\n if (isPositiveSafeInteger(value) && value > maxUsed) maxUsed = value\n }\n let free = maxUsed < Number.MAX_SAFE_INTEGER ? maxUsed + 1 : 1\n const allocateFree = (): number => {\n while (used.has(free)) {\n free = free < Number.MAX_SAFE_INTEGER ? free + 1 : 1\n }\n const assigned = free\n used.add(assigned)\n free = assigned < Number.MAX_SAFE_INTEGER ? assigned + 1 : 1\n return assigned\n }\n\n const remap = new Map<number, number>()\n const blocks = carried.map((block) => {\n if (!used.has(block.seq)) {\n used.add(block.seq)\n return block\n }\n const seq = allocateFree()\n remap.set(block.seq, seq)\n return { ...block, seq }\n })\n\n if (!remap.size) return { text, blocks }\n\n let out = text\n const ranges = findTokenRanges(text, carried)\n for (let index = ranges.length - 1; index >= 0; index -= 1) {\n const { start, end, block } = ranges[index]!\n const mapped = remap.get(block.seq)\n if (mapped === undefined) continue\n out = out.slice(0, start) + formatToken({ ...block, seq: mapped }) + out.slice(end)\n }\n return { text: out, blocks }\n}\n\n/** Ranges for canonical tokens whose sequence and line count match one block. */\nexport function findTokenRanges(\n text: string,\n blocks: readonly PasteBlock[]\n): Array<{ start: number; end: number; block: PasteBlock }> {\n if (!text || !blocks.length) return []\n const bySeq = new Map(unambiguousBlocks(blocks).map((block) => [block.seq, block]))\n if (!bySeq.size) return []\n\n const tokenRegex = new RegExp(PASTE_TOKEN_SOURCE, 'g')\n const ranges: Array<{ start: number; end: number; block: PasteBlock }> = []\n let match: RegExpExecArray | null\n while ((match = tokenRegex.exec(text)) !== null) {\n const seq = Number(match[1])\n const lines = Number(match[2])\n if (!isPositiveSafeInteger(seq) || !isPositiveSafeInteger(lines)) continue\n const block = bySeq.get(seq)\n if (block && block.lines === lines) {\n ranges.push({ start: match.index, end: match.index + match[0].length, block })\n }\n }\n return ranges\n}\n\nexport function tokenRangeAt(\n text: string,\n blocks: readonly PasteBlock[],\n caret: number\n): { start: number; end: number; block: PasteBlock } | null {\n if (!Number.isSafeInteger(caret) || caret < 0 || caret > text.length) return null\n for (const range of findTokenRanges(text, blocks)) {\n if (caret >= range.start && caret <= range.end) return range\n }\n return null\n}\n\nexport function pruneBlocks(text: string, blocks: PasteBlock[]): PasteBlock[] {\n if (!blocks.length) return blocks\n const usable = unambiguousBlocks(blocks)\n const survivors = new Set(findTokenRanges(text, usable).map((range) => range.block.id))\n const next = usable.filter((block) => survivors.has(block.id))\n return next.length === blocks.length && next.every((block, index) => block === blocks[index])\n ? blocks\n : next\n}\n\nexport function expandAll(text: string, blocks: readonly PasteBlock[]): string {\n if (!text || !blocks.length) return text\n const ranges = findTokenRanges(text, blocks)\n if (!ranges.length) return text\n let out = text\n for (let index = ranges.length - 1; index >= 0; index -= 1) {\n const range = ranges[index]!\n out = out.slice(0, range.start) + range.block.content + out.slice(range.end)\n }\n return out\n}\n\n/** Inverse of `expandAll`: replace each first non-overlapping verbatim block. */\nexport function recollapsePastes(content: string, blocks: readonly PasteBlock[]): string {\n if (!content || !blocks.length) return content\n\n interface Hit {\n start: number\n end: number\n block: PasteBlock\n }\n const hits: Hit[] = []\n const claimed: Array<[number, number]> = []\n const firstUnclaimed = (needle: string): number => {\n if (!needle) return -1\n let from = 0\n while (from <= content.length) {\n const index = content.indexOf(needle, from)\n if (index < 0) return -1\n if (!claimed.some(([start, end]) => index < end && index + needle.length > start))\n return index\n from = index + 1\n }\n return -1\n }\n\n for (const block of unambiguousBlocks(blocks)) {\n if (!block.content) continue\n const trimmed = block.content.trimEnd()\n let needle = block.content\n let index = firstUnclaimed(needle)\n if (index < 0 && trimmed && trimmed !== block.content) {\n needle = trimmed\n index = firstUnclaimed(needle)\n }\n if (index < 0) continue\n const end = index + needle.length\n hits.push({ start: index, end, block })\n claimed.push([index, end])\n }\n\n if (!hits.length) return content\n hits.sort((left, right) => left.start - right.start)\n let out = ''\n let position = 0\n for (const hit of hits) {\n if (hit.start < position) continue\n out += content.slice(position, hit.start) + formatToken(hit.block)\n position = hit.end\n }\n return out + content.slice(position)\n}\n\n/** Strip a trailing whitespace run only when that run contains a newline. */\nexport function stripTrailingBlankLines(value: string): string {\n let index = value.length - 1\n let sawNewline = false\n while (index >= 0) {\n const code = value.charCodeAt(index)\n if (code === 10 || code === 13) {\n sawNewline = true\n index -= 1\n continue\n }\n if (code === 32 || code === 9) {\n index -= 1\n continue\n }\n break\n }\n return sawNewline ? value.slice(0, index + 1) : value\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"split-layout.d.ts","sourceRoot":"","sources":["../../../../src/components/layout/split-layout/split-layout.tsx"],"names":[],"mappings":"AACA,OAAO,EAQL,KAAK,QAAQ,EACb,KAAK,GAAG,EACT,MAAM,UAAU,CAAA;AAKjB,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,QAAQ,CAAA;AAC5D,YAAY,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAA;AAE5C,OAAO,EAIL,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACtB,MAAM,SAAS,CAAA;AAEhB,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,eAAe,IAAI;IACxD,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAA;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,8DAA8D;IAC9D,YAAY,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAA;IACjC,yFAAyF;IACzF,UAAU,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAA;IAC9C,yFAAyF;IACzF,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAA;IACpD,+GAA+G;IAC/G,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;IACrB,oFAAoF;IACpF,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,MAAM,CAAA;IAC5D,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAClD,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,sFAAsF;IACtF,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAA;IAChD,qGAAqG;IACrG,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,KAAK,IAAI,CAAA;IAC3E,qFAAqF;IACrF,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAA;IACtD,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AASD,mGAAmG;AACnG,wBAAgB,WAAW,CAAC,CAAC,SAAS,eAAe,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,eA6RhF"}
1
+ {"version":3,"file":"split-layout.d.ts","sourceRoot":"","sources":["../../../../src/components/layout/split-layout/split-layout.tsx"],"names":[],"mappings":"AACA,OAAO,EAQL,KAAK,QAAQ,EACb,KAAK,GAAG,EACT,MAAM,UAAU,CAAA;AAKjB,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,QAAQ,CAAA;AAC5D,YAAY,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAA;AAE5C,OAAO,EAIL,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACtB,MAAM,SAAS,CAAA;AAEhB,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,eAAe,IAAI;IACxD,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAA;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,8DAA8D;IAC9D,YAAY,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAA;IACjC,yFAAyF;IACzF,UAAU,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAA;IAC9C,yFAAyF;IACzF,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAA;IACpD,+GAA+G;IAC/G,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;IACrB,oFAAoF;IACpF,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,MAAM,CAAA;IAC5D,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAClD,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,sFAAsF;IACtF,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAA;IAChD,qGAAqG;IACrG,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,KAAK,IAAI,CAAA;IAC3E,qFAAqF;IACrF,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAA;IACtD,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AASD,mGAAmG;AACnG,wBAAgB,WAAW,CAAC,CAAC,SAAS,eAAe,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,eAuShF"}
@@ -248,6 +248,8 @@ function SplitLayout(props) {
248
248
  },
249
249
  keyboardDelta: .05,
250
250
  onSizesChange: (sizes) => {
251
+ if (!root?.isConnected || root.getClientRects().length === 0) return;
252
+ if (sizes.length !== 2 || sizes.some((size) => !Number.isFinite(size)) || Math.abs(sizes[0] + sizes[1] - 1) > 1e-6) return;
251
253
  if (sizes[0] !== void 0 && Math.abs(sizes[0] - branch().ratio) > 1e-6) props.onResize(id, sizes[0]);
252
254
  },
253
255
  get style() {
@@ -1 +1 @@
1
- {"version":3,"file":"split-layout.js","names":["Resizable","For","createMemo","createComputed","createUniqueId","createSignal","onCleanup","on","Accessor","JSX","X","GripVertical","Button","cn","computeLayoutFrames","LayoutRect","paneDropIntent","PaneDropIntent","PANE_DRAG_TYPE","listLeaves","MIN_SPLIT_RATIO","MAX_SPLIT_RATIO","SplitLayoutBranch","SplitLayoutLeaf","SplitLayoutState","SplitLayoutProps","state","L","label","labelForLeaf","leaf","renderLeaf","Element","renderPaneLabel","paneTabIndex","labelForSeparator","branch","onResize","splitId","ratio","onFocus","leafId","onClose","onMove","targetId","intent","renderPaneActions","class","rectStyle","rect","CSSProperties","left","x","top","y","width","height","SplitLayout","props","root","HTMLDivElement","pendingFrame","refs","Map","HTMLElement","domIds","prefix","nextDomId","nextDragId","drag","setDrag","id","token","drop","setDrop","clearDrag","undefined","domId","existing","get","created","set","leaves","center","leafMap","map","frames","branches","Array","from","values","flatMap","frame","node","kind","current","has","target","allowedTarget","transfer","DataTransfer","types","includes","dropLabel","placement","branchMap","schedule","action","cancelAnimationFrame","requestAnimationFrame","active","ownerDocument","activeElement","contains","field","HTMLTextAreaElement","HTMLInputElement","selection","start","selectionStart","end","selectionEnd","direction","selectionDirection","isConnected","body","focus","preventScroll","setSelectionRange","clear","close","next","_el$","_tmpl$","_el$2","firstChild","_$use","el","_$insert","_$createComponent","each","children","initial","content","paneLabel","actions","delete","_el$3","_tmpl$2","_el$4","_el$5","_el$6","_el$7","nextSibling","$$focusin","addEventListener","event","dataTransfer","clientX","clientY","currentTarget","getBoundingClientRect","accepted","getData","preventDefault","relatedTarget","Node","dropEffect","_$setAttribute","setData","effectAllowed","_c$","_$memo","_c$2","variant","size","aria-label","onClick","_c$3","_el$8","_tmpl$3","_$effect","_$className","_p$","_v$3","_v$4","_v$5","_v$6","focusedLeafId","_v$7","_v$8","_v$9","_v$0","Boolean","_v$1","e","t","a","o","i","n","s","_$style","h","r","orientation","sizes","keyboardDelta","onSizesChange","Math","abs","style","Panel","minSize","maxSize","Handle","aria-orientation","aria-controls","join","aria-valuenow","round","_v$","_v$2","_$delegateEvents","_$createComponent","_$memo","_$className","_$setAttribute","_$style","_$delegateEvents"],"sources":["../../../../src/components/layout/split-layout/split-layout.tsx"],"sourcesContent":["import Resizable from '@corvu/resizable'\nimport {\n For,\n createMemo,\n createComputed,\n createUniqueId,\n createSignal,\n onCleanup,\n on,\n type Accessor,\n type JSX,\n} from 'solid-js'\nimport { X, GripVertical } from 'lucide-solid'\nimport { Button } from '../../ui/button'\nimport { cn } from '#lib/utils'\nimport { computeLayoutFrames, type LayoutRect } from './geometry'\nimport { paneDropIntent, type PaneDropIntent } from './drop'\nexport type { PaneDropIntent } from './drop'\nconst PANE_DRAG_TYPE = 'application/x-adea-pane-move'\nimport {\n listLeaves,\n MIN_SPLIT_RATIO,\n MAX_SPLIT_RATIO,\n type SplitLayoutBranch,\n type SplitLayoutLeaf,\n type SplitLayoutState,\n} from './model'\n\nexport type SplitLayoutProps<L extends SplitLayoutLeaf> = {\n state: SplitLayoutState<L>\n label: string\n /** Accessible name for a pane region and its close button. */\n labelForLeaf: (leaf: L) => string\n /** Called once per stable leaf owner; the accessor tracks opaque payload replacement. */\n renderLeaf: (leaf: Accessor<L>) => JSX.Element\n /** Inline visible header composition, separate from the region and close-button name. */\n renderPaneLabel?: (leaf: Accessor<L>) => JSX.Element\n /** Whether pane regions participate in sequential keyboard navigation; defaults to programmatic focus only. */\n paneTabIndex?: 0 | -1\n /** Accessible splitter name; defaults to the current orientation-specific label. */\n labelForSeparator?: (branch: SplitLayoutBranch<L>) => string\n onResize: (splitId: string, ratio: number) => void\n onFocus?: (leafId: string) => void\n /** Host performs the model transition and returns the surviving focus destination. */\n onClose?: (leafId: string) => string | undefined\n /** Pointer placement only; the host supplies keyboard commands and performs the model transition. */\n onMove?: (leafId: string, targetId: string, intent: PaneDropIntent) => void\n /** Stable header composition for host-owned keyboard actions/capability feedback. */\n renderPaneActions?: (leaf: Accessor<L>) => JSX.Element\n class?: string\n}\nfunction rectStyle(rect: LayoutRect): JSX.CSSProperties {\n return {\n left: `${rect.x * 100}%`,\n top: `${rect.y * 100}%`,\n width: `${rect.width * 100}%`,\n height: `${rect.height * 100}%`,\n }\n}\n/** Muxy frame geometry keeps leaf owners stable; Corvu owns constrained separator interactions. */\nexport function SplitLayout<L extends SplitLayoutLeaf>(props: SplitLayoutProps<L>) {\n let root: HTMLDivElement | undefined\n let pendingFrame: number | undefined\n const refs = new Map<string, HTMLElement>()\n const domIds = new Map<string, string>()\n const prefix = createUniqueId()\n let nextDomId = 0\n let nextDragId = 0\n const [drag, setDrag] = createSignal<{ id: string; token: string }>()\n const [drop, setDrop] = createSignal<{ id: string; intent: PaneDropIntent }>()\n const clearDrag = () => {\n setDrag(undefined)\n setDrop(undefined)\n }\n const domId = (id: string) => {\n const existing = domIds.get(id)\n if (existing) return existing\n const created = `${prefix}-pane-${nextDomId++}`\n domIds.set(id, created)\n return created\n }\n const leaves = createMemo(() => listLeaves(props.state.center))\n const leafMap = createMemo(() => new Map(leaves().map((leaf) => [leaf.id, leaf])))\n const frames = createMemo(() => computeLayoutFrames(props.state.center))\n const branches = createMemo(() =>\n Array.from(frames().values()).flatMap((frame) =>\n frame.node.kind === 'split' ? [frame.node] : []\n )\n )\n createComputed(() => {\n const current = drag()\n if (current && (!props.onMove || !leafMap().has(current.id))) clearDrag()\n const target = drop()\n if (target && !leafMap().has(target.id)) setDrop(undefined)\n })\n const allowedTarget = (id: string, transfer: DataTransfer | null) => {\n const current = drag()\n return props.onMove &&\n current &&\n current.id !== id &&\n leafMap().has(current.id) &&\n leafMap().has(id) &&\n transfer?.types.includes(PANE_DRAG_TYPE)\n ? current\n : undefined\n }\n const dropLabel = createMemo(() => {\n const target = drop()\n const leaf = target ? leafMap().get(target.id) : undefined\n return target && leaf\n ? `Drop to place pane ${target.intent.placement} ${props.labelForLeaf(leaf)}`\n : ''\n })\n const branchMap = createMemo(() => new Map(branches().map((branch) => [branch.id, branch])))\n const schedule = (action: () => void) => {\n if (pendingFrame !== undefined) cancelAnimationFrame(pendingFrame)\n pendingFrame = requestAnimationFrame(() => {\n pendingFrame = undefined\n action()\n })\n }\n // Register before keyed children update: capture a focused editor before an\n // ordered DOM move can blur it. Never override a newer focus outside this root.\n createComputed(\n on(\n () => props.state.center,\n () => {\n const active = root?.ownerDocument.activeElement\n if (!root || !(active instanceof HTMLElement) || !root.contains(active)) return\n const field =\n active instanceof HTMLTextAreaElement || active instanceof HTMLInputElement\n ? active\n : undefined\n const selection = field\n ? {\n start: field.selectionStart,\n end: field.selectionEnd,\n direction: field.selectionDirection,\n }\n : undefined\n schedule(() => {\n if (!active.isConnected || !root?.contains(active)) return\n const current = active.ownerDocument.activeElement\n if (current !== active && current !== active.ownerDocument.body) return\n active.focus({ preventScroll: true })\n if (field && selection?.start !== null && selection?.end !== null && selection)\n field.setSelectionRange(\n selection.start,\n selection.end,\n selection.direction ?? undefined\n )\n })\n }\n )\n )\n onCleanup(() => {\n if (pendingFrame !== undefined) cancelAnimationFrame(pendingFrame)\n clearDrag()\n refs.clear()\n domIds.clear()\n })\n const close = (id: string) => {\n const next = props.onClose?.(id)\n if (next) schedule(() => refs.get(next)?.focus({ preventScroll: true }))\n }\n return (\n <div\n ref={(el) => {\n root = el\n }}\n role=\"group\"\n aria-label={props.label}\n data-slot=\"split-layout\"\n class={cn('relative size-full min-h-0 min-w-0', props.class)}\n >\n <For each={leaves().map((leaf) => leaf.id)}>\n {(id) => {\n const initial = leafMap().get(id)!\n const leaf = () => leafMap().get(id) ?? initial\n const content = props.renderLeaf(leaf)\n const paneLabel = props.renderPaneLabel?.(leaf)\n const actions = props.renderPaneActions?.(leaf)\n const intent = () => (drop()?.id === id ? drop()?.intent : undefined)\n onCleanup(() => {\n refs.delete(id)\n domIds.delete(id)\n })\n return (\n <section\n ref={(el) => refs.set(id, el)}\n id={domId(id)}\n role=\"region\"\n aria-label={props.labelForLeaf(leaf())}\n tabIndex={props.paneTabIndex ?? -1}\n data-pane-id={id}\n data-focused={props.state.focusedLeafId === id ? '' : undefined}\n data-drop-direction={intent()?.direction}\n data-drop-placement={intent()?.placement}\n onDragOver={(event) => {\n if (!allowedTarget(id, event.dataTransfer)) return\n const next = paneDropIntent(\n event.clientX,\n event.clientY,\n event.currentTarget.getBoundingClientRect()\n )\n if (!next) {\n setDrop(undefined)\n return\n }\n event.preventDefault()\n if (event.dataTransfer) event.dataTransfer.dropEffect = 'move'\n setDrop({ id, intent: next })\n }}\n onDragLeave={(event) => {\n if (\n event.relatedTarget instanceof Node &&\n event.currentTarget.contains(event.relatedTarget)\n )\n return\n if (drop()?.id === id) setDrop(undefined)\n }}\n onDrop={(event) => {\n const current = allowedTarget(id, event.dataTransfer)\n const next = paneDropIntent(\n event.clientX,\n event.clientY,\n event.currentTarget.getBoundingClientRect()\n )\n const accepted =\n current && next && event.dataTransfer?.getData(PANE_DRAG_TYPE) === current.token\n clearDrag()\n if (!accepted) return\n event.preventDefault()\n props.onMove?.(current.id, id, next)\n }}\n style={rectStyle(frames().get(id)?.rect ?? { x: 0, y: 0, width: 0, height: 0 })}\n class=\"absolute flex min-h-0 min-w-0 flex-col overflow-hidden border border-border data-[focused]:border-primary bg-background text-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring\"\n onFocusIn={() => props.onFocus?.(id)}\n >\n <header class=\"flex min-w-0 shrink-0 items-center gap-2 bg-surface px-2\">\n <span\n data-pane-drag-handle=\"\"\n draggable={Boolean(props.onMove)}\n class=\"flex min-w-0 flex-1 items-center gap-2 truncate text-sm\"\n title={props.onMove ? `Drag ${props.labelForLeaf(leaf())} to move` : undefined}\n onDragStart={(event) => {\n if (!props.onMove || !event.dataTransfer) {\n event.preventDefault()\n return\n }\n const token = `${prefix}-${++nextDragId}`\n setDrag({ id, token })\n event.dataTransfer.setData(PANE_DRAG_TYPE, token)\n event.dataTransfer.effectAllowed = 'move'\n }}\n onDragEnd={clearDrag}\n >\n {props.onMove ? (\n <GripVertical class=\"size-3 shrink-0\" aria-hidden=\"true\" />\n ) : null}\n <span class=\"min-w-0 flex-1 truncate\">\n {paneLabel ?? props.labelForLeaf(leaf())}\n </span>\n </span>\n {actions}\n {props.onClose ? (\n <Button\n variant=\"ghost\"\n size=\"icon-xs\"\n aria-label={`Close ${props.labelForLeaf(leaf())}`}\n onClick={() => close(id)}\n >\n <X />\n </Button>\n ) : null}\n </header>\n <div class=\"min-h-0 min-w-0 flex-1 overflow-auto\">{content}</div>\n {intent() ? (\n <div\n aria-hidden=\"true\"\n class={cn('pointer-events-none absolute border-2 border-primary bg-primary/10', {\n 'inset-y-0 left-0 w-1/2':\n intent()?.direction === 'row' && intent()?.placement === 'before',\n 'inset-y-0 right-0 w-1/2':\n intent()?.direction === 'row' && intent()?.placement === 'after',\n 'inset-x-0 top-0 h-1/2':\n intent()?.direction === 'column' && intent()?.placement === 'before',\n 'inset-x-0 bottom-0 h-1/2':\n intent()?.direction === 'column' && intent()?.placement === 'after',\n })}\n />\n ) : null}\n </section>\n )\n }}\n </For>\n <span class=\"sr-only\" role=\"status\">\n {dropLabel()}\n </span>\n <For each={branches().map((branch) => branch.id)}>\n {(id) => {\n const initial = branchMap().get(id)!\n const branch: Accessor<SplitLayoutBranch<L>> = () => branchMap().get(id) ?? initial\n return (\n <Resizable\n orientation={branch().direction === 'row' ? 'horizontal' : 'vertical'}\n sizes={[branch().ratio, 1 - branch().ratio]}\n keyboardDelta={0.05}\n onSizesChange={(sizes) => {\n if (sizes[0] !== undefined && Math.abs(sizes[0] - branch().ratio) > 0.000001)\n props.onResize(id, sizes[0])\n }}\n style={rectStyle(frames().get(id)?.rect ?? { x: 0, y: 0, width: 0, height: 0 })}\n class=\"pointer-events-none absolute flex min-h-0 min-w-0 data-[orientation=vertical]:flex-col\"\n >\n <Resizable.Panel\n minSize={MIN_SPLIT_RATIO}\n maxSize={MAX_SPLIT_RATIO}\n aria-hidden=\"true\"\n />\n <Resizable.Handle\n aria-label={\n props.labelForSeparator?.(branch()) ??\n (branch().direction === 'row' ? 'Resize pane columns' : 'Resize pane rows')\n }\n aria-orientation={branch().direction === 'row' ? 'vertical' : 'horizontal'}\n aria-controls={listLeaves(branch())\n .map((leaf) => domId(leaf.id))\n .join(' ')}\n aria-valuemin={10}\n aria-valuemax={90}\n aria-valuenow={Math.round(branch().ratio * 100)}\n class=\"pointer-events-auto relative w-px shrink-0 bg-border after:absolute after:inset-y-0 after:-inset-x-1 after:w-3 focus-visible:bg-primary focus-visible:outline-none hover:bg-primary data-[orientation=vertical]:h-px data-[orientation=vertical]:w-full data-[orientation=vertical]:after:inset-x-0 data-[orientation=vertical]:after:-inset-y-1 data-[orientation=vertical]:after:h-3 data-[orientation=vertical]:after:w-full\"\n />\n <Resizable.Panel\n minSize={MIN_SPLIT_RATIO}\n maxSize={MAX_SPLIT_RATIO}\n aria-hidden=\"true\"\n />\n </Resizable>\n )\n }}\n </For>\n </div>\n )\n}\n"],"mappings":";;;;;;;;;;;;;AAkBA,IAAMkB,iBAAiB;AAiCvB,SAAS8B,UAAUC,MAAqC;CACtD,OAAO;EACLE,MAAM,GAAGF,KAAKG,IAAI,IAAG;EACrBC,KAAK,GAAGJ,KAAKK,IAAI,IAAG;EACpBC,OAAO,GAAGN,KAAKM,QAAQ,IAAG;EAC1BC,QAAQ,GAAGP,KAAKO,SAAS,IAAG;CAC9B;AACF;;AAEA,SAAgBC,YAAuCC,OAA4B;CACjF,IAAIC;CACJ,IAAIE;CACJ,MAAMC,uBAAO,IAAIC,IAAyB;CAC1C,MAAME,yBAAS,IAAIF,IAAoB;CACvC,MAAMG,SAAS9D,eAAe;CAC9B,IAAI+D,YAAY;CAChB,IAAIC,aAAa;CACjB,MAAM,CAACC,MAAMC,WAAWjE,aAA4C;CACpE,MAAM,CAACoE,MAAMC,WAAWrE,aAAqD;CAC7E,MAAMsE,kBAAkB;EACtBL,QAAQM,KAAAA,CAAS;EACjBF,QAAQE,KAAAA,CAAS;CACnB;CACA,MAAMC,SAASN,OAAe;EAC5B,MAAMO,WAAWb,OAAOc,IAAIR,EAAE;EAC9B,IAAIO,UAAU,OAAOA;EACrB,MAAME,UAAU,GAAGd,OAAM,QAASC;EAClCF,OAAOgB,IAAIV,IAAIS,OAAO;EACtB,OAAOA;CACT;CACA,MAAME,SAAShF,iBAAiBiB,WAAWuC,MAAMhC,MAAMyD,MAAM,CAAC;CAC9D,MAAMC,UAAUlF,iBAAiB,IAAI6D,IAAImB,OAAO,CAAC,CAACG,KAAKvD,SAAS,CAACA,KAAKyC,IAAIzC,IAAI,CAAC,CAAC,CAAC;CACjF,MAAMwD,SAASpF,iBAAiBY,oBAAoB4C,MAAMhC,MAAMyD,MAAM,CAAC;CACvE,MAAMI,WAAWrF,iBACfsF,MAAMC,KAAKH,OAAO,CAAC,CAACI,OAAO,CAAC,CAAC,CAACC,SAASC,UACrCA,MAAMC,KAAKC,SAAS,UAAU,CAACF,MAAMC,IAAI,IAAI,CAAA,CAC/C,CACF;CACA1F,qBAAqB;EACnB,MAAM4F,UAAU1B,KAAK;EACrB,IAAI0B,YAAY,CAACrC,MAAMf,UAAU,CAACyC,QAAQ,CAAC,CAACY,IAAID,QAAQxB,EAAE,IAAII,UAAU;EACxE,MAAMsB,SAASxB,KAAK;EACpB,IAAIwB,UAAU,CAACb,QAAQ,CAAC,CAACY,IAAIC,OAAO1B,EAAE,GAAGG,QAAQE,KAAAA,CAAS;CAC5D,CAAC;CACD,MAAMsB,iBAAiB3B,IAAY4B,aAAkC;EACnE,MAAMJ,UAAU1B,KAAK;EACrB,OAAOX,MAAMf,UACXoD,WACAA,QAAQxB,OAAOA,MACfa,QAAQ,CAAC,CAACY,IAAID,QAAQxB,EAAE,KACxBa,QAAQ,CAAC,CAACY,IAAIzB,EAAE,KAChB4B,UAAUE,MAAMC,SAASpF,cAAc,IACrC6E,UACAnB,KAAAA;CACN;CACA,MAAM2B,YAAYrG,iBAAiB;EACjC,MAAM+F,SAASxB,KAAK;EACpB,MAAM3C,OAAOmE,SAASb,QAAQ,CAAC,CAACL,IAAIkB,OAAO1B,EAAE,IAAIK,KAAAA;EACjD,OAAOqB,UAAUnE,OACb,sBAAsBmE,OAAOpD,OAAO2D,UAAS,GAAI9C,MAAM7B,aAAaC,IAAI,MACxE;CACN,CAAC;CACD,MAAM2E,YAAYvG,iBAAiB,IAAI6D,IAAIwB,SAAS,CAAC,CAACF,KAAKjD,WAAW,CAACA,OAAOmC,IAAInC,MAAM,CAAC,CAAC,CAAC;CAC3F,MAAMsE,YAAYC,WAAuB;EACvC,IAAI9C,iBAAiBe,KAAAA,GAAWgC,qBAAqB/C,YAAY;EACjEA,eAAegD,4BAA4B;GACzChD,eAAee,KAAAA;GACf+B,OAAO;EACT,CAAC;CACH;CAGAxG,eACEI,SACQmD,MAAMhC,MAAMyD,cACZ;EACJ,MAAM2B,SAASnD,MAAMoD,cAAcC;EACnC,IAAI,CAACrD,QAAQ,EAAEmD,kBAAkB9C,gBAAgB,CAACL,KAAKsD,SAASH,MAAM,GAAG;EACzE,MAAMI,QACJJ,kBAAkBK,uBAAuBL,kBAAkBM,mBACvDN,SACAlC,KAAAA;EACN,MAAMyC,YAAYH,QACd;GACEI,OAAOJ,MAAMK;GACbC,KAAKN,MAAMO;GACXC,WAAWR,MAAMS;EACnB,IACA/C,KAAAA;EACJ8B,eAAe;GACb,IAAI,CAACI,OAAOc,eAAe,CAACjE,MAAMsD,SAASH,MAAM,GAAG;GACpD,MAAMf,UAAUe,OAAOC,cAAcC;GACrC,IAAIjB,YAAYe,UAAUf,YAAYe,OAAOC,cAAcc,MAAM;GACjEf,OAAOgB,MAAM,EAAEC,eAAe,KAAK,CAAC;GACpC,IAAIb,SAASG,WAAWC,UAAU,QAAQD,WAAWG,QAAQ,QAAQH,WACnEH,MAAMc,kBACJX,UAAUC,OACVD,UAAUG,KACVH,UAAUK,aAAa9C,KAAAA,CACzB;EACJ,CAAC;CACH,CACF,CACF;CACAtE,gBAAgB;EACd,IAAIuD,iBAAiBe,KAAAA,GAAWgC,qBAAqB/C,YAAY;EACjEc,UAAU;EACVb,KAAKmE,MAAM;EACXhE,OAAOgE,MAAM;CACf,CAAC;CACD,MAAMC,SAAS3D,OAAe;EAC5B,MAAM4D,OAAOzE,MAAMhB,UAAU6B,EAAE;EAC/B,IAAI4D,MAAMzB,eAAe5C,KAAKiB,IAAIoD,IAAI,CAAC,EAAEL,MAAM,EAAEC,eAAe,KAAK,CAAC,CAAC;CACzE;CACA,cAAA;EAAA,IAAAK,OAAAC,OAAA,GAAAC,QAAAF,KAAAG;EAAAC,KAEUC,OAAO;GACX9E,OAAO8E;EACT,GAACL,IAAA;EAAAM,OAAAN,MAAAO,gBAMA1I,KAAG;GAAA,IAAC2I,OAAI;IAAA,OAAE1D,OAAO,CAAC,CAACG,KAAKvD,SAASA,KAAKyC,EAAE;GAAC;GAAAsE,WACtCtE,OAAO;IACP,MAAMuE,UAAU1D,QAAQ,CAAC,CAACL,IAAIR,EAAE;IAChC,MAAMzC,aAAasD,QAAQ,CAAC,CAACL,IAAIR,EAAE,KAAKuE;IACxC,MAAMC,UAAUrF,MAAM3B,WAAWD,IAAI;IACrC,MAAMkH,YAAYtF,MAAMzB,kBAAkBH,IAAI;IAC9C,MAAMmH,UAAUvF,MAAMZ,oBAAoBhB,IAAI;IAC9C,MAAMe,eAAgB4B,KAAK,CAAC,EAAEF,OAAOA,KAAKE,KAAK,CAAC,EAAE5B,SAAS+B,KAAAA;IAC3DtE,gBAAgB;KACdwD,KAAKoF,OAAO3E,EAAE;KACdN,OAAOiF,OAAO3E,EAAE;IAClB,CAAC;IACD,cAAA;KAAA,IAAA4E,QAAAC,QAAA,GAAAC,QAAAF,MAAAZ,YAAAe,QAAAD,MAAAd,YAAAgB,QAAAD,MAAAf,YAAAiB,QAAAH,MAAAI;KAAAN,MAAAO,kBAkDqBhG,MAAMlB,UAAU+B,EAAE;KAAC4E,MAAAQ,iBAAA,SAhB3BC,UAAU;MACjB,MAAM7D,UAAUG,cAAc3B,IAAIqF,MAAMC,YAAY;MACpD,MAAM1B,OAAOnH,eACX4I,MAAME,SACNF,MAAMG,SACNH,MAAMI,cAAcC,sBAAsB,CAC5C;MACA,MAAMC,WACJnE,WAAWoC,QAAQyB,MAAMC,cAAcM,QAAQjJ,cAAc,MAAM6E,QAAQvB;MAC7EG,UAAU;MACV,IAAI,CAACuF,UAAU;MACfN,MAAMQ,eAAe;MACrB1G,MAAMf,SAASoD,QAAQxB,IAAIA,IAAI4D,IAAI;KACrC,CAAC;KAAAgB,MAAAQ,iBAAA,cArBaC,UAAU;MACtB,IACEA,MAAMS,yBAAyBC,QAC/BV,MAAMI,cAAc/C,SAAS2C,MAAMS,aAAa,GAEhD;MACF,IAAI5F,KAAK,CAAC,EAAEF,OAAOA,IAAIG,QAAQE,KAAAA,CAAS;KAC1C,CAAC;KAAAuE,MAAAQ,iBAAA,aAtBYC,UAAU;MACrB,IAAI,CAAC1D,cAAc3B,IAAIqF,MAAMC,YAAY,GAAG;MAC5C,MAAM1B,OAAOnH,eACX4I,MAAME,SACNF,MAAMG,SACNH,MAAMI,cAAcC,sBAAsB,CAC5C;MACA,IAAI,CAAC9B,MAAM;OACTzD,QAAQE,KAAAA,CAAS;OACjB;MACF;MACAgF,MAAMQ,eAAe;MACrB,IAAIR,MAAMC,cAAcD,MAAMC,aAAaU,aAAa;MACxD7F,QAAQ;OAAEH;OAAI1B,QAAQsF;MAAK,CAAC;KAC9B,CAAC;KAAAK,KAvBKC,OAAO3E,KAAKmB,IAAIV,IAAIkE,EAAE,GAACU,KAAA;KAAAqB,aAAArB,OAAA,gBAKf5E,EAAE;KAAA+E,MAAAK,iBAAA,WA6DDhF,SAAS;KAAA2E,MAAAK,iBAAA,cAVNC,UAAU;MACtB,IAAI,CAAClG,MAAMf,UAAU,CAACiH,MAAMC,cAAc;OACxCD,MAAMQ,eAAe;OACrB;MACF;MACA,MAAM5F,QAAQ,GAAGN,OAAM,GAAI,EAAEE;MAC7BE,QAAQ;OAAEC;OAAIC;MAAM,CAAC;MACrBoF,MAAMC,aAAaY,QAAQvJ,gBAAgBsD,KAAK;MAChDoF,MAAMC,aAAaa,gBAAgB;KACrC,CAAC;KAAAhC,OAAAY,cAAA;MAAA,IAAAqB,MAAAC,WAAA,CAAA,CAGAlH,MAAMf,MAAM;MAAA,aAAZgI,IAAA,IAAAhC,gBACEhI,cAAY;OAAA,SAAA;OAAA,eAAA;MAAA,CAAA,IACX;KAAI,EAAA,CAAA,GAAA4I,KAAA;KAAAb,OAAAa,aAELP,aAAatF,MAAM7B,aAAaC,KAAK,CAAC,CAAC;KAAA4G,OAAAW,OAG3CJ,SAAO,IAAA;KAAAP,OAAAW,cAAA;MAAA,IAAAwB,OAAAD,WAAA,CAAA,CACPlH,MAAMhB,OAAO;MAAA,aAAbmI,KAAA,IAAAlC,gBACE/H,QAAM;OACLkK,SAAO;OACPC,MAAI;OAAA,KAAA,gBAAA;QAAA,OACQ,SAASrH,MAAM7B,aAAaC,KAAK,CAAC;OAAG;OACjDmJ,eAAe/C,MAAM3D,EAAE;OAAC,IAAAsE,WAAA;QAAA,OAAAF,gBAEvBjI,GAAC,CAAA,CAAA;OAAA;MAAA,CAAA,IAEF;KAAI,EAAA,CAAA,GAAA,IAAA;KAAAgI,OAAAc,OAEyCT,OAAO;KAAAL,OAAAS,cAAA;MAAA,IAAA+B,OAAAN,WAAA,CAAA,CACzD/H,OAAO,CAAC;MAAA,aAARqI,KAAA,WAAA;OAAA,IAAAC,QAAAC,QAAA;OAAAC,aAAAC,UAAAH,OAGUtK,GAAG,sEAAsE;QAC9E,0BACEgC,OAAO,CAAC,EAAE6E,cAAc,SAAS7E,OAAO,CAAC,EAAE2D,cAAc;QAC3D,2BACE3D,OAAO,CAAC,EAAE6E,cAAc,SAAS7E,OAAO,CAAC,EAAE2D,cAAc;QAC3D,yBACE3D,OAAO,CAAC,EAAE6E,cAAc,YAAY7E,OAAO,CAAC,EAAE2D,cAAc;QAC9D,4BACE3D,OAAO,CAAC,EAAE6E,cAAc,YAAY7E,OAAO,CAAC,EAAE2D,cAAc;OAChE,CAAC,CAAC,CAAA;OAAA,OAAA2E;MAAA,EAAA,CAAA,IAEF;KAAI,EAAA,CAAA,GAAA,IAAA;KAAAE,QAAAE,QAAA;MAAA,IAAAC,OArGJ3G,MAAMN,EAAE,GAACkH,OAED/H,MAAM7B,aAAaC,KAAK,CAAC,GAAC4J,OAC5BhI,MAAMxB,gBAAgB,IAAEyJ,OAEpBjI,MAAMhC,MAAMkK,kBAAkBrH,KAAK,KAAKK,KAAAA,GAASiH,OAC1ChJ,OAAO,CAAC,EAAE6E,WAASoE,OACnBjJ,OAAO,CAAC,EAAE2D,WAASuF,OAsCjC/I,UAAUsC,OAAO,CAAC,CAACP,IAAIR,EAAE,CAAC,EAAEtB,QAAQ;OAAEG,GAAG;OAAGE,GAAG;OAAGC,OAAO;OAAGC,QAAQ;MAAE,CAAC,GAACwI,OAOhEC,QAAQvI,MAAMf,MAAM,GAACuJ,OAEzBxI,MAAMf,SAAS,QAAQe,MAAM7B,aAAaC,KAAK,CAAC,EAAC,YAAa8C,KAAAA;MAAS4G,SAAAD,IAAAY,KAAA3B,aAAArB,OAAA,MAAAoC,IAAAY,IAAAX,IAAA;MAAAC,SAAAF,IAAAa,KAAA5B,aAAArB,OAAA,cAAAoC,IAAAa,IAAAX,IAAA;MAAAC,SAAAH,IAAAc,KAAA7B,aAAArB,OAAA,YAAAoC,IAAAc,IAAAX,IAAA;MAAAC,SAAAJ,IAAAe,KAAA9B,aAAArB,OAAA,gBAAAoC,IAAAe,IAAAX,IAAA;MAAAE,SAAAN,IAAAgB,KAAA/B,aAAArB,OAAA,uBAAAoC,IAAAgB,IAAAV,IAAA;MAAAC,SAAAP,IAAAiB,KAAAhC,aAAArB,OAAA,uBAAAoC,IAAAiB,IAAAV,IAAA;MAAAP,IAAAkB,IAAAC,MAAAvD,OAAA4C,MAAAR,IAAAkB,CAAA;MAAAT,SAAAT,IAAAoB,KAAAnC,aAAAlB,OAAA,aAAAiC,IAAAoB,IAAAX,IAAA;MAAAE,SAAAX,IAAAqB,KAAApC,aAAAlB,OAAA,SAAAiC,IAAAqB,IAAAV,IAAA;MAAA,OAAAX;KAAA,GAAA;MAAAY,GAAAvH,KAAAA;MAAAwH,GAAAxH,KAAAA;MAAAyH,GAAAzH,KAAAA;MAAA0H,GAAA1H,KAAAA;MAAA2H,GAAA3H,KAAAA;MAAA4H,GAAA5H,KAAAA;MAAA6H,GAAA7H,KAAAA;MAAA+H,GAAA/H,KAAAA;MAAAgI,GAAAhI,KAAAA;KAAA,CAAA;KAAA,OAAAuE;IAAA,EAAA,CAAA;GAkDxF;EAAC,CAAA,GAAAb,KAAA;EAAAI,OAAAJ,OAGA/B,SAAS;EAAAmC,OAAAN,MAAAO,gBAEX1I,KAAG;GAAA,IAAC2I,OAAI;IAAA,OAAErD,SAAS,CAAC,CAACF,KAAKjD,WAAWA,OAAOmC,EAAE;GAAC;GAAAsE,WAC5CtE,OAAO;IACP,MAAMuE,UAAUrC,UAAU,CAAC,CAAC1B,IAAIR,EAAE;IAClC,MAAMnC,eAA+CqE,UAAU,CAAC,CAAC1B,IAAIR,EAAE,KAAKuE;IAC5E,OAAAH,gBACG3I,WAAS;KAAA,IACR6M,cAAW;MAAA,OAAEzK,OAAO,CAAC,CAACsF,cAAc,QAAQ,eAAe;KAAU;KAAA,IACrEoF,QAAK;MAAA,OAAE,CAAC1K,OAAO,CAAC,CAACG,OAAO,IAAIH,OAAO,CAAC,CAACG,KAAK;KAAC;KAC3CwK,eAAe;KACfC,gBAAgBF,UAAU;MACxB,IAAIA,MAAM,OAAOlI,KAAAA,KAAaqI,KAAKC,IAAIJ,MAAM,KAAK1K,OAAO,CAAC,CAACG,KAAK,IAAI,MAClEmB,MAAMrB,SAASkC,IAAIuI,MAAM,EAAE;KAC/B;KAAC,IACDK,QAAK;MAAA,OAAEnK,UAAUsC,OAAO,CAAC,CAACP,IAAIR,EAAE,CAAC,EAAEtB,QAAQ;OAAEG,GAAG;OAAGE,GAAG;OAAGC,OAAO;OAAGC,QAAQ;MAAE,CAAC;KAAC;KAAA,SAAA;KAAA,IAAAqF,WAAA;MAAA,OAAA;OAAAF,gBAG9E3I,UAAUoN,OAAK;QACdC,SAASjM;QACTkM,SAASjM;QAAe,eAAA;OAAA,CAAA;OAAAsH,gBAGzB3I,UAAUuN,QAAM;QAAA,KAAA,gBAAA;SAAA,OAEb7J,MAAMvB,oBAAoBC,OAAO,CAAC,MACjCA,OAAO,CAAC,CAACsF,cAAc,QAAQ,wBAAwB;QAAmB;QAAA,KAAA,sBAAA;SAAA,OAE3DtF,OAAO,CAAC,CAACsF,cAAc,QAAQ,aAAa;QAAY;QAAA,KAAA,mBAAA;SAAA,OAC3DvG,WAAWiB,OAAO,CAAC,CAAC,CAChCiD,KAAKvD,SAAS+C,MAAM/C,KAAKyC,EAAE,CAAC,CAAC,CAC7BmJ,KAAK,GAAG;QAAC;QAAA,iBACG;QAAE,iBACF;QAAE,KAAA,mBAAA;SAAA,OACFT,KAAKW,MAAMxL,OAAO,CAAC,CAACG,QAAQ,GAAG;QAAC;QAAA,SAAA;OAAA,CAAA;OAAAoG,gBAGhD3I,UAAUoN,OAAK;QACdC,SAASjM;QACTkM,SAASjM;QAAe,eAAA;OAAA,CAAA;MAAA;KAAA;IAAA,CAAA;GAKhC;EAAC,CAAA,GAAA,IAAA;EAAAgK,QAAAE,QAAA;GAAA,IAAAsC,MA1KSnK,MAAM9B,OAAKkM,OAEhBjN,GAAG,sCAAsC6C,MAAMX,KAAK;GAAC8K,QAAAtC,IAAAY,KAAA3B,aAAApC,MAAA,cAAAmD,IAAAY,IAAA0B,GAAA;GAAAC,SAAAvC,IAAAa,KAAAd,UAAAlD,MAAAmD,IAAAa,IAAA0B,IAAA;GAAA,OAAAvC;EAAA,GAAA;GAAAY,GAAAvH,KAAAA;GAAAwH,GAAAxH,KAAAA;EAAA,CAAA;EAAA,OAAAwD;CAAA,EAAA,CAAA;AA4KlE;AAAC2F,eAAA,CAAA,SAAA,CAAA"}
1
+ {"version":3,"file":"split-layout.js","names":["Resizable","For","createMemo","createComputed","createUniqueId","createSignal","onCleanup","on","Accessor","JSX","X","GripVertical","Button","cn","computeLayoutFrames","LayoutRect","paneDropIntent","PaneDropIntent","PANE_DRAG_TYPE","listLeaves","MIN_SPLIT_RATIO","MAX_SPLIT_RATIO","SplitLayoutBranch","SplitLayoutLeaf","SplitLayoutState","SplitLayoutProps","state","L","label","labelForLeaf","leaf","renderLeaf","Element","renderPaneLabel","paneTabIndex","labelForSeparator","branch","onResize","splitId","ratio","onFocus","leafId","onClose","onMove","targetId","intent","renderPaneActions","class","rectStyle","rect","CSSProperties","left","x","top","y","width","height","SplitLayout","props","root","HTMLDivElement","pendingFrame","refs","Map","HTMLElement","domIds","prefix","nextDomId","nextDragId","drag","setDrag","id","token","drop","setDrop","clearDrag","undefined","domId","existing","get","created","set","leaves","center","leafMap","map","frames","branches","Array","from","values","flatMap","frame","node","kind","current","has","target","allowedTarget","transfer","DataTransfer","types","includes","dropLabel","placement","branchMap","schedule","action","cancelAnimationFrame","requestAnimationFrame","active","ownerDocument","activeElement","contains","field","HTMLTextAreaElement","HTMLInputElement","selection","start","selectionStart","end","selectionEnd","direction","selectionDirection","isConnected","body","focus","preventScroll","setSelectionRange","clear","close","next","_el$","_tmpl$","_el$2","firstChild","_$use","el","_$insert","_$createComponent","each","children","initial","content","paneLabel","actions","delete","_el$3","_tmpl$2","_el$4","_el$5","_el$6","_el$7","nextSibling","$$focusin","addEventListener","event","dataTransfer","clientX","clientY","currentTarget","getBoundingClientRect","accepted","getData","preventDefault","relatedTarget","Node","dropEffect","_$setAttribute","setData","effectAllowed","_c$","_$memo","_c$2","variant","size","aria-label","onClick","_c$3","_el$8","_tmpl$3","_$effect","_$className","_p$","_v$3","_v$4","_v$5","_v$6","focusedLeafId","_v$7","_v$8","_v$9","_v$0","Boolean","_v$1","e","t","a","o","i","n","s","_$style","h","r","orientation","sizes","keyboardDelta","onSizesChange","getClientRects","length","some","Number","isFinite","Math","abs","style","Panel","minSize","maxSize","Handle","aria-orientation","aria-controls","join","aria-valuenow","round","_v$","_v$2","_$delegateEvents","_$createComponent","_$memo","_$className","_$setAttribute","_$style","_$delegateEvents"],"sources":["../../../../src/components/layout/split-layout/split-layout.tsx"],"sourcesContent":["import Resizable from '@corvu/resizable'\nimport {\n For,\n createMemo,\n createComputed,\n createUniqueId,\n createSignal,\n onCleanup,\n on,\n type Accessor,\n type JSX,\n} from 'solid-js'\nimport { X, GripVertical } from 'lucide-solid'\nimport { Button } from '../../ui/button'\nimport { cn } from '#lib/utils'\nimport { computeLayoutFrames, type LayoutRect } from './geometry'\nimport { paneDropIntent, type PaneDropIntent } from './drop'\nexport type { PaneDropIntent } from './drop'\nconst PANE_DRAG_TYPE = 'application/x-adea-pane-move'\nimport {\n listLeaves,\n MIN_SPLIT_RATIO,\n MAX_SPLIT_RATIO,\n type SplitLayoutBranch,\n type SplitLayoutLeaf,\n type SplitLayoutState,\n} from './model'\n\nexport type SplitLayoutProps<L extends SplitLayoutLeaf> = {\n state: SplitLayoutState<L>\n label: string\n /** Accessible name for a pane region and its close button. */\n labelForLeaf: (leaf: L) => string\n /** Called once per stable leaf owner; the accessor tracks opaque payload replacement. */\n renderLeaf: (leaf: Accessor<L>) => JSX.Element\n /** Inline visible header composition, separate from the region and close-button name. */\n renderPaneLabel?: (leaf: Accessor<L>) => JSX.Element\n /** Whether pane regions participate in sequential keyboard navigation; defaults to programmatic focus only. */\n paneTabIndex?: 0 | -1\n /** Accessible splitter name; defaults to the current orientation-specific label. */\n labelForSeparator?: (branch: SplitLayoutBranch<L>) => string\n onResize: (splitId: string, ratio: number) => void\n onFocus?: (leafId: string) => void\n /** Host performs the model transition and returns the surviving focus destination. */\n onClose?: (leafId: string) => string | undefined\n /** Pointer placement only; the host supplies keyboard commands and performs the model transition. */\n onMove?: (leafId: string, targetId: string, intent: PaneDropIntent) => void\n /** Stable header composition for host-owned keyboard actions/capability feedback. */\n renderPaneActions?: (leaf: Accessor<L>) => JSX.Element\n class?: string\n}\nfunction rectStyle(rect: LayoutRect): JSX.CSSProperties {\n return {\n left: `${rect.x * 100}%`,\n top: `${rect.y * 100}%`,\n width: `${rect.width * 100}%`,\n height: `${rect.height * 100}%`,\n }\n}\n/** Muxy frame geometry keeps leaf owners stable; Corvu owns constrained separator interactions. */\nexport function SplitLayout<L extends SplitLayoutLeaf>(props: SplitLayoutProps<L>) {\n let root: HTMLDivElement | undefined\n let pendingFrame: number | undefined\n const refs = new Map<string, HTMLElement>()\n const domIds = new Map<string, string>()\n const prefix = createUniqueId()\n let nextDomId = 0\n let nextDragId = 0\n const [drag, setDrag] = createSignal<{ id: string; token: string }>()\n const [drop, setDrop] = createSignal<{ id: string; intent: PaneDropIntent }>()\n const clearDrag = () => {\n setDrag(undefined)\n setDrop(undefined)\n }\n const domId = (id: string) => {\n const existing = domIds.get(id)\n if (existing) return existing\n const created = `${prefix}-pane-${nextDomId++}`\n domIds.set(id, created)\n return created\n }\n const leaves = createMemo(() => listLeaves(props.state.center))\n const leafMap = createMemo(() => new Map(leaves().map((leaf) => [leaf.id, leaf])))\n const frames = createMemo(() => computeLayoutFrames(props.state.center))\n const branches = createMemo(() =>\n Array.from(frames().values()).flatMap((frame) =>\n frame.node.kind === 'split' ? [frame.node] : []\n )\n )\n createComputed(() => {\n const current = drag()\n if (current && (!props.onMove || !leafMap().has(current.id))) clearDrag()\n const target = drop()\n if (target && !leafMap().has(target.id)) setDrop(undefined)\n })\n const allowedTarget = (id: string, transfer: DataTransfer | null) => {\n const current = drag()\n return props.onMove &&\n current &&\n current.id !== id &&\n leafMap().has(current.id) &&\n leafMap().has(id) &&\n transfer?.types.includes(PANE_DRAG_TYPE)\n ? current\n : undefined\n }\n const dropLabel = createMemo(() => {\n const target = drop()\n const leaf = target ? leafMap().get(target.id) : undefined\n return target && leaf\n ? `Drop to place pane ${target.intent.placement} ${props.labelForLeaf(leaf)}`\n : ''\n })\n const branchMap = createMemo(() => new Map(branches().map((branch) => [branch.id, branch])))\n const schedule = (action: () => void) => {\n if (pendingFrame !== undefined) cancelAnimationFrame(pendingFrame)\n pendingFrame = requestAnimationFrame(() => {\n pendingFrame = undefined\n action()\n })\n }\n // Register before keyed children update: capture a focused editor before an\n // ordered DOM move can blur it. Never override a newer focus outside this root.\n createComputed(\n on(\n () => props.state.center,\n () => {\n const active = root?.ownerDocument.activeElement\n if (!root || !(active instanceof HTMLElement) || !root.contains(active)) return\n const field =\n active instanceof HTMLTextAreaElement || active instanceof HTMLInputElement\n ? active\n : undefined\n const selection = field\n ? {\n start: field.selectionStart,\n end: field.selectionEnd,\n direction: field.selectionDirection,\n }\n : undefined\n schedule(() => {\n if (!active.isConnected || !root?.contains(active)) return\n const current = active.ownerDocument.activeElement\n if (current !== active && current !== active.ownerDocument.body) return\n active.focus({ preventScroll: true })\n if (field && selection?.start !== null && selection?.end !== null && selection)\n field.setSelectionRange(\n selection.start,\n selection.end,\n selection.direction ?? undefined\n )\n })\n }\n )\n )\n onCleanup(() => {\n if (pendingFrame !== undefined) cancelAnimationFrame(pendingFrame)\n clearDrag()\n refs.clear()\n domIds.clear()\n })\n const close = (id: string) => {\n const next = props.onClose?.(id)\n if (next) schedule(() => refs.get(next)?.focus({ preventScroll: true }))\n }\n return (\n <div\n ref={(el) => {\n root = el\n }}\n role=\"group\"\n aria-label={props.label}\n data-slot=\"split-layout\"\n class={cn('relative size-full min-h-0 min-w-0', props.class)}\n >\n <For each={leaves().map((leaf) => leaf.id)}>\n {(id) => {\n const initial = leafMap().get(id)!\n const leaf = () => leafMap().get(id) ?? initial\n const content = props.renderLeaf(leaf)\n const paneLabel = props.renderPaneLabel?.(leaf)\n const actions = props.renderPaneActions?.(leaf)\n const intent = () => (drop()?.id === id ? drop()?.intent : undefined)\n onCleanup(() => {\n refs.delete(id)\n domIds.delete(id)\n })\n return (\n <section\n ref={(el) => refs.set(id, el)}\n id={domId(id)}\n role=\"region\"\n aria-label={props.labelForLeaf(leaf())}\n tabIndex={props.paneTabIndex ?? -1}\n data-pane-id={id}\n data-focused={props.state.focusedLeafId === id ? '' : undefined}\n data-drop-direction={intent()?.direction}\n data-drop-placement={intent()?.placement}\n onDragOver={(event) => {\n if (!allowedTarget(id, event.dataTransfer)) return\n const next = paneDropIntent(\n event.clientX,\n event.clientY,\n event.currentTarget.getBoundingClientRect()\n )\n if (!next) {\n setDrop(undefined)\n return\n }\n event.preventDefault()\n if (event.dataTransfer) event.dataTransfer.dropEffect = 'move'\n setDrop({ id, intent: next })\n }}\n onDragLeave={(event) => {\n if (\n event.relatedTarget instanceof Node &&\n event.currentTarget.contains(event.relatedTarget)\n )\n return\n if (drop()?.id === id) setDrop(undefined)\n }}\n onDrop={(event) => {\n const current = allowedTarget(id, event.dataTransfer)\n const next = paneDropIntent(\n event.clientX,\n event.clientY,\n event.currentTarget.getBoundingClientRect()\n )\n const accepted =\n current && next && event.dataTransfer?.getData(PANE_DRAG_TYPE) === current.token\n clearDrag()\n if (!accepted) return\n event.preventDefault()\n props.onMove?.(current.id, id, next)\n }}\n style={rectStyle(frames().get(id)?.rect ?? { x: 0, y: 0, width: 0, height: 0 })}\n class=\"absolute flex min-h-0 min-w-0 flex-col overflow-hidden border border-border data-[focused]:border-primary bg-background text-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring\"\n onFocusIn={() => props.onFocus?.(id)}\n >\n <header class=\"flex min-w-0 shrink-0 items-center gap-2 bg-surface px-2\">\n <span\n data-pane-drag-handle=\"\"\n draggable={Boolean(props.onMove)}\n class=\"flex min-w-0 flex-1 items-center gap-2 truncate text-sm\"\n title={props.onMove ? `Drag ${props.labelForLeaf(leaf())} to move` : undefined}\n onDragStart={(event) => {\n if (!props.onMove || !event.dataTransfer) {\n event.preventDefault()\n return\n }\n const token = `${prefix}-${++nextDragId}`\n setDrag({ id, token })\n event.dataTransfer.setData(PANE_DRAG_TYPE, token)\n event.dataTransfer.effectAllowed = 'move'\n }}\n onDragEnd={clearDrag}\n >\n {props.onMove ? (\n <GripVertical class=\"size-3 shrink-0\" aria-hidden=\"true\" />\n ) : null}\n <span class=\"min-w-0 flex-1 truncate\">\n {paneLabel ?? props.labelForLeaf(leaf())}\n </span>\n </span>\n {actions}\n {props.onClose ? (\n <Button\n variant=\"ghost\"\n size=\"icon-xs\"\n aria-label={`Close ${props.labelForLeaf(leaf())}`}\n onClick={() => close(id)}\n >\n <X />\n </Button>\n ) : null}\n </header>\n <div class=\"min-h-0 min-w-0 flex-1 overflow-auto\">{content}</div>\n {intent() ? (\n <div\n aria-hidden=\"true\"\n class={cn('pointer-events-none absolute border-2 border-primary bg-primary/10', {\n 'inset-y-0 left-0 w-1/2':\n intent()?.direction === 'row' && intent()?.placement === 'before',\n 'inset-y-0 right-0 w-1/2':\n intent()?.direction === 'row' && intent()?.placement === 'after',\n 'inset-x-0 top-0 h-1/2':\n intent()?.direction === 'column' && intent()?.placement === 'before',\n 'inset-x-0 bottom-0 h-1/2':\n intent()?.direction === 'column' && intent()?.placement === 'after',\n })}\n />\n ) : null}\n </section>\n )\n }}\n </For>\n <span class=\"sr-only\" role=\"status\">\n {dropLabel()}\n </span>\n <For each={branches().map((branch) => branch.id)}>\n {(id) => {\n const initial = branchMap().get(id)!\n const branch: Accessor<SplitLayoutBranch<L>> = () => branchMap().get(id) ?? initial\n return (\n <Resizable\n orientation={branch().direction === 'row' ? 'horizontal' : 'vertical'}\n sizes={[branch().ratio, 1 - branch().ratio]}\n keyboardDelta={0.05}\n onSizesChange={(sizes) => {\n // Corvu also reports panel registration/unregistration while\n // mounting or disposing a controller. Those incomplete or\n // hidden-host sizes are not user resize intent.\n if (!root?.isConnected || root.getClientRects().length === 0) return\n if (\n sizes.length !== 2 ||\n sizes.some((size) => !Number.isFinite(size)) ||\n Math.abs(sizes[0]! + sizes[1]! - 1) > 0.000001\n )\n return\n if (sizes[0] !== undefined && Math.abs(sizes[0] - branch().ratio) > 0.000001)\n props.onResize(id, sizes[0])\n }}\n style={rectStyle(frames().get(id)?.rect ?? { x: 0, y: 0, width: 0, height: 0 })}\n class=\"pointer-events-none absolute flex min-h-0 min-w-0 data-[orientation=vertical]:flex-col\"\n >\n <Resizable.Panel\n minSize={MIN_SPLIT_RATIO}\n maxSize={MAX_SPLIT_RATIO}\n aria-hidden=\"true\"\n />\n <Resizable.Handle\n aria-label={\n props.labelForSeparator?.(branch()) ??\n (branch().direction === 'row' ? 'Resize pane columns' : 'Resize pane rows')\n }\n aria-orientation={branch().direction === 'row' ? 'vertical' : 'horizontal'}\n aria-controls={listLeaves(branch())\n .map((leaf) => domId(leaf.id))\n .join(' ')}\n aria-valuemin={10}\n aria-valuemax={90}\n aria-valuenow={Math.round(branch().ratio * 100)}\n class=\"pointer-events-auto relative w-px shrink-0 bg-border after:absolute after:inset-y-0 after:-inset-x-1 after:w-3 focus-visible:bg-primary focus-visible:outline-none hover:bg-primary data-[orientation=vertical]:h-px data-[orientation=vertical]:w-full data-[orientation=vertical]:after:inset-x-0 data-[orientation=vertical]:after:-inset-y-1 data-[orientation=vertical]:after:h-3 data-[orientation=vertical]:after:w-full\"\n />\n <Resizable.Panel\n minSize={MIN_SPLIT_RATIO}\n maxSize={MAX_SPLIT_RATIO}\n aria-hidden=\"true\"\n />\n </Resizable>\n )\n }}\n </For>\n </div>\n )\n}\n"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -77,6 +77,7 @@ import { ConversationSurface } from "./components/conversation/conversation-surf
77
77
  import { ComposerAttachmentButton, ComposerHint, MessageComposer } from "./components/conversation/message-composer.js";
78
78
  import { MessageBody, MessageDayDivider, MessageGroup, MessageRow } from "./components/conversation/message-row.js";
79
79
  import { AttachmentCard, ThreadPanel } from "./components/conversation/thread-panel.js";
80
+ import { PASTE_THRESHOLD_CHARS, PASTE_THRESHOLD_LINES, PASTE_TOKEN_REGEX, countLines, expandAll, findTokenRanges, formatToken, isPasteBlock, nextSeq, pruneBlocks, recollapsePastes, remapCarriedBlocks, shouldCollapse, stripTrailingBlankLines, tokenRangeAt } from "./components/conversation/paste-tokens.js";
80
81
  import { accentPresets, allTokens, colorTokens, densityTokens, designTokens, elevationTokens, fontOptions, motionTokens, radiusTokens, typographyTokens, undocumentedTokenAliases, zIndexTokens } from "./lib/tokens.js";
81
82
  import { builtinThemes, contrastRatio, defaultDarkThemeId, defaultLightThemeId, themeById, themeCssVariables, themeFamilies, themesForAppearance, validateTheme, validateThemeRegistry } from "./lib/themes.js";
82
83
  import { ThemePicker, ThemePreview, ThemeSwatch } from "./components/theme/theme-picker.js";
@@ -93,4 +94,4 @@ import { formatBytes, formatReleaseDate, plainTextFromMarkdown } from "./lib/ver
93
94
  import { UpdateDialog } from "./components/composites/update-dialog/update-dialog.js";
94
95
  import { WorkspaceMark } from "./components/composites/workspace-mark/workspace-mark.js";
95
96
  import { keyedRows } from "./lib/keyed-rows.js";
96
- export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, AccountMenu, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AppShell, AppShellBody, AppShellContent, AppShellMain, AppearanceEditor, AppearancePanel, AppearancePopover, AspectRatio, AttachmentCard, Avatar, AvatarFallback, AvatarImage, Badge, Board, BoardCardBody, BoardCardTitle, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbSeparator, BusySendButton, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, CalendarSurface, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, ChatComposer, Checkbox, CheckboxDescription, CheckboxLabel, CodeBlock, Collapsible, CollapsibleContent, CollapsibleTrigger, Combobox, ComboboxClear, ComboboxContent, ComboboxControl, ComboboxInput, ComboboxItem, ComboboxSection, ComboboxTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandLoading, CommandSeparator, CommandShortcut, ComposerAttachmentButton, ComposerHint, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, ConversationAvatar, ConversationSurface, DatePicker, DetailPanel, DetailPanelBody, DetailPanelField, DetailPanelHeader, DetailPanelSection, Dialog, DialogClose, DialogCloseButton, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DiffBlock, DiffSummary, Drawer, DrawerBody, DrawerCloseButton, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, EntityIcon, Field, FieldDescription, FieldError, FieldInput, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTextArea, HoverCard, HoverCardContent, HoverCardTrigger, InlineCode, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputOtp, InputOtpCaret, Item, ItemDescription, ItemEmpty, ItemGroup, ItemGroupEntry, ItemTitle, Kbd, KbdGroup, Label, ListGroup, ListRow, MAX_LAYOUT_DEPTH, MAX_LAYOUT_LEAVES, MAX_SPLIT_RATIO, MIN_SPLIT_RATIO, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, MessageBody, MessageComposer, MessageDayDivider, MessageGroup, MessageRow, ModalDialog, Motion, NavigationMenu, NavigationMenuContent, NavigationMenuGroup, NavigationMenuGroupLabel, NavigationMenuItem, NavigationMenuMenu, NavigationMenuSeparator, NavigationMenuTrigger, NavigationMenuViewport, Page, PageHeader, PageHeaderActions, PageHeaderContent, PageHeaderDescription, PageHeaderTitle, PageSection, Pagination, PaginationEllipsis, PaginationItem, PaginationNext, PaginationPrevious, PalettePreview, Panel, PanelActions, PanelBody, PanelCard, PanelDescription, PanelFooter, PanelHeader, PanelPlaceholder, PanelTitle, PanelToolbar, Popover, PopoverAnchor, PopoverCloseButton, PopoverContent, PopoverDescription, PopoverTitle, PopoverTrigger, Presence, Progress, PropertyList, PropertyRow, PropertyTerm, PropertyValue, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, ScrollArea, Select, SelectChevronsUpDown, SelectContent, SelectItem, SelectLabel, SelectSection, SelectTrigger, SelectValue, Separator, SettingsField, SettingsPage, SettingsRow, SettingsSection, Sheet, SheetBody, SheetCloseButton, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, SideRail, SideRailButton, SideRailContent, SideRailFooter, SideRailHeader, SideRailItem, SideRailSection, SidebarNav, SidebarNavButton, SidebarNavContent, SidebarNavFooter, SidebarNavHeader, SidebarNavItem, SidebarNavSection, SidebarNavTitle, Skeleton, Slider, Spinner, SplitLayout, Stat, StatGroup, StatusBar, StatusBarItem, StatusBarSpacer, StatusChip, StatusList, Switch, SwitchDescription, SwitchLabel, TALL_CODE_BLOCK_PX, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableNumericCell, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, ThemeMiniature, ThemeMiniatureSplit, ThemePicker, ThemePreview, ThemeProvider, ThemeSwatch, ThemeToggle, ThreadPanel, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TopBar, TopBarBreadcrumb, TopBarPill, TopBarSearch, TopBarSection, TopBarTitle, UpdateDialog, WorkspaceMark, accentPresets, alertVariants, allTokens, badgeVariants, boardCardTitleVariants, builtinThemes, buttonVariants, closePane, cn, colorTokens, computeLayoutFrames, contrastRatio, controlInteractive, controlSize, controlSizeIcon, controlSizes, countLeaves, createLayoutState, cva, defaultDarkThemeId, defaultLightThemeId, defaultThemeSelection, densityTokens, designTokens, diffLineVariants, diffStats, diffTargetPath, elevationTokens, entityIconVariants, focusPane, fontOptions, formatBytes, formatReleaseDate, initialsFrom, inlineScriptLiteral, itemVariants, keyedRows, layoutDepth, listLeaves, monogram, motionTokens, movePane, neighborLeaf, normalizeLayout, parseDiff, plainTextFromMarkdown, radiusTokens, resizeSplit, resolvedDensity, sheetVariants, sidebarNavItemClass, sidebarNavItemStateClass, splitPane, statusDotVariants, surfaceInteractive, swapPanes, themeById, themeCssVariables, themeFamilies, themeScript, themesForAppearance, toast, toaster, toggleVariants, typographyTokens, undoClosePane, undocumentedTokenAliases, useSideRail, useTheme, validateTheme, validateThemeRegistry, zIndexTokens };
97
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, AccountMenu, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AppShell, AppShellBody, AppShellContent, AppShellMain, AppearanceEditor, AppearancePanel, AppearancePopover, AspectRatio, AttachmentCard, Avatar, AvatarFallback, AvatarImage, Badge, Board, BoardCardBody, BoardCardTitle, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbSeparator, BusySendButton, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, CalendarSurface, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, ChatComposer, Checkbox, CheckboxDescription, CheckboxLabel, CodeBlock, Collapsible, CollapsibleContent, CollapsibleTrigger, Combobox, ComboboxClear, ComboboxContent, ComboboxControl, ComboboxInput, ComboboxItem, ComboboxSection, ComboboxTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandLoading, CommandSeparator, CommandShortcut, ComposerAttachmentButton, ComposerHint, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, ConversationAvatar, ConversationSurface, DatePicker, DetailPanel, DetailPanelBody, DetailPanelField, DetailPanelHeader, DetailPanelSection, Dialog, DialogClose, DialogCloseButton, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DiffBlock, DiffSummary, Drawer, DrawerBody, DrawerCloseButton, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, EntityIcon, Field, FieldDescription, FieldError, FieldInput, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTextArea, HoverCard, HoverCardContent, HoverCardTrigger, InlineCode, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputOtp, InputOtpCaret, Item, ItemDescription, ItemEmpty, ItemGroup, ItemGroupEntry, ItemTitle, Kbd, KbdGroup, Label, ListGroup, ListRow, MAX_LAYOUT_DEPTH, MAX_LAYOUT_LEAVES, MAX_SPLIT_RATIO, MIN_SPLIT_RATIO, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, MessageBody, MessageComposer, MessageDayDivider, MessageGroup, MessageRow, ModalDialog, Motion, NavigationMenu, NavigationMenuContent, NavigationMenuGroup, NavigationMenuGroupLabel, NavigationMenuItem, NavigationMenuMenu, NavigationMenuSeparator, NavigationMenuTrigger, NavigationMenuViewport, PASTE_THRESHOLD_CHARS, PASTE_THRESHOLD_LINES, PASTE_TOKEN_REGEX, Page, PageHeader, PageHeaderActions, PageHeaderContent, PageHeaderDescription, PageHeaderTitle, PageSection, Pagination, PaginationEllipsis, PaginationItem, PaginationNext, PaginationPrevious, PalettePreview, Panel, PanelActions, PanelBody, PanelCard, PanelDescription, PanelFooter, PanelHeader, PanelPlaceholder, PanelTitle, PanelToolbar, Popover, PopoverAnchor, PopoverCloseButton, PopoverContent, PopoverDescription, PopoverTitle, PopoverTrigger, Presence, Progress, PropertyList, PropertyRow, PropertyTerm, PropertyValue, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, ScrollArea, Select, SelectChevronsUpDown, SelectContent, SelectItem, SelectLabel, SelectSection, SelectTrigger, SelectValue, Separator, SettingsField, SettingsPage, SettingsRow, SettingsSection, Sheet, SheetBody, SheetCloseButton, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, SideRail, SideRailButton, SideRailContent, SideRailFooter, SideRailHeader, SideRailItem, SideRailSection, SidebarNav, SidebarNavButton, SidebarNavContent, SidebarNavFooter, SidebarNavHeader, SidebarNavItem, SidebarNavSection, SidebarNavTitle, Skeleton, Slider, Spinner, SplitLayout, Stat, StatGroup, StatusBar, StatusBarItem, StatusBarSpacer, StatusChip, StatusList, Switch, SwitchDescription, SwitchLabel, TALL_CODE_BLOCK_PX, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableNumericCell, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, ThemeMiniature, ThemeMiniatureSplit, ThemePicker, ThemePreview, ThemeProvider, ThemeSwatch, ThemeToggle, ThreadPanel, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TopBar, TopBarBreadcrumb, TopBarPill, TopBarSearch, TopBarSection, TopBarTitle, UpdateDialog, WorkspaceMark, accentPresets, alertVariants, allTokens, badgeVariants, boardCardTitleVariants, builtinThemes, buttonVariants, closePane, cn, colorTokens, computeLayoutFrames, contrastRatio, controlInteractive, controlSize, controlSizeIcon, controlSizes, countLeaves, countLines, createLayoutState, cva, defaultDarkThemeId, defaultLightThemeId, defaultThemeSelection, densityTokens, designTokens, diffLineVariants, diffStats, diffTargetPath, elevationTokens, entityIconVariants, expandAll, findTokenRanges, focusPane, fontOptions, formatBytes, formatReleaseDate, formatToken, initialsFrom, inlineScriptLiteral, isPasteBlock, itemVariants, keyedRows, layoutDepth, listLeaves, monogram, motionTokens, movePane, neighborLeaf, nextSeq, normalizeLayout, parseDiff, plainTextFromMarkdown, pruneBlocks, radiusTokens, recollapsePastes, remapCarriedBlocks, resizeSplit, resolvedDensity, sheetVariants, shouldCollapse, sidebarNavItemClass, sidebarNavItemStateClass, splitPane, statusDotVariants, stripTrailingBlankLines, surfaceInteractive, swapPanes, themeById, themeCssVariables, themeFamilies, themeScript, themesForAppearance, toast, toaster, toggleVariants, tokenRangeAt, typographyTokens, undoClosePane, undocumentedTokenAliases, useSideRail, useTheme, validateTheme, validateThemeRegistry, zIndexTokens };