@emdash-cms/admin 0.37.0 → 0.39.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/LocaleDirectionProvider-DK_kkYCq.js +62 -0
- package/dist/LocaleDirectionProvider-DK_kkYCq.js.map +1 -0
- package/dist/{config-DAMBKrx2.d.ts → config-DXYw_Bmz.d.ts} +1 -1
- package/dist/{config-DAMBKrx2.d.ts.map → config-DXYw_Bmz.d.ts.map} +1 -1
- package/dist/index.d.ts +163 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14220 -9404
- package/dist/index.js.map +1 -1
- package/dist/{LocaleDirectionProvider-DWBtquoB.js → loadMessages-CJphypuw.js} +36 -89
- package/dist/loadMessages-CJphypuw.js.map +1 -0
- package/dist/locales/ar/messages.mjs +1 -1
- package/dist/locales/ca/messages.mjs +1 -1
- package/dist/locales/cs/messages.mjs +1 -1
- package/dist/locales/de/messages.mjs +1 -1
- package/dist/locales/en/messages.mjs +1 -1
- package/dist/locales/en-GB/messages.mjs +1 -1
- package/dist/locales/es-419/messages.mjs +1 -1
- package/dist/locales/es-ES/messages.mjs +1 -1
- package/dist/locales/eu/messages.mjs +1 -1
- package/dist/locales/fa/messages.mjs +1 -1
- package/dist/locales/fr/messages.mjs +1 -1
- package/dist/locales/hi/messages.mjs +1 -1
- package/dist/locales/hu/messages.mjs +1 -1
- package/dist/locales/id/messages.mjs +1 -1
- package/dist/locales/index.d.ts +1 -1
- package/dist/locales/index.js +2 -1
- package/dist/locales/ja/messages.mjs +1 -1
- package/dist/locales/ka/messages.mjs +1 -0
- package/dist/locales/ko/messages.mjs +1 -1
- package/dist/locales/nb/messages.mjs +1 -1
- package/dist/locales/nl/messages.mjs +1 -1
- package/dist/locales/pl/messages.mjs +1 -1
- package/dist/locales/pseudo/messages.mjs +1 -1
- package/dist/locales/pt-BR/messages.mjs +1 -1
- package/dist/locales/server.d.ts +18 -0
- package/dist/locales/server.d.ts.map +1 -0
- package/dist/locales/server.js +62 -0
- package/dist/locales/server.js.map +1 -0
- package/dist/locales/sr-Latn/messages.mjs +1 -1
- package/dist/locales/sv/messages.mjs +1 -1
- package/dist/locales/th/messages.mjs +1 -1
- package/dist/locales/tr/messages.mjs +1 -1
- package/dist/locales/uk/messages.mjs +1 -1
- package/dist/locales/zh-CN/messages.mjs +1 -1
- package/dist/locales/zh-TW/messages.mjs +1 -1
- package/dist/messages-4feGwM08.js +6 -0
- package/dist/messages-4feGwM08.js.map +1 -0
- package/dist/messages-4sxjbkLR.js +6 -0
- package/dist/messages-4sxjbkLR.js.map +1 -0
- package/dist/messages-9FxexJts.js +6 -0
- package/dist/messages-9FxexJts.js.map +1 -0
- package/dist/messages-BB4IYKOM.js +6 -0
- package/dist/messages-BB4IYKOM.js.map +1 -0
- package/dist/messages-BDVupe2R.js +6 -0
- package/dist/messages-BDVupe2R.js.map +1 -0
- package/dist/messages-BEzSJOgq.js +6 -0
- package/dist/messages-BEzSJOgq.js.map +1 -0
- package/dist/messages-BNbfC4gr.js +6 -0
- package/dist/messages-BNbfC4gr.js.map +1 -0
- package/dist/messages-BtybIcYp.js +6 -0
- package/dist/messages-BtybIcYp.js.map +1 -0
- package/dist/messages-C-lfe55s.js +6 -0
- package/dist/messages-C-lfe55s.js.map +1 -0
- package/dist/messages-C71z_Olc.js +6 -0
- package/dist/messages-C71z_Olc.js.map +1 -0
- package/dist/messages-C7l5VBoa.js +6 -0
- package/dist/messages-C7l5VBoa.js.map +1 -0
- package/dist/messages-CHpfgEvy.js +6 -0
- package/dist/messages-CHpfgEvy.js.map +1 -0
- package/dist/messages-CJJNploj.js +6 -0
- package/dist/messages-CJJNploj.js.map +1 -0
- package/dist/messages-CLvJyGlQ.js +6 -0
- package/dist/messages-CLvJyGlQ.js.map +1 -0
- package/dist/messages-CfJsX0R2.js +6 -0
- package/dist/messages-CfJsX0R2.js.map +1 -0
- package/dist/messages-Cna0C_WI.js +6 -0
- package/dist/messages-Cna0C_WI.js.map +1 -0
- package/dist/messages-Cw9egXze.js +6 -0
- package/dist/messages-Cw9egXze.js.map +1 -0
- package/dist/messages-D1WuB6yv.js +6 -0
- package/dist/messages-D1WuB6yv.js.map +1 -0
- package/dist/messages-D3Kphmv9.js +6 -0
- package/dist/messages-D3Kphmv9.js.map +1 -0
- package/dist/messages-DArLJJ89.js +6 -0
- package/dist/messages-DArLJJ89.js.map +1 -0
- package/dist/messages-DEmESFdp.js +6 -0
- package/dist/messages-DEmESFdp.js.map +1 -0
- package/dist/messages-DJR8CYOj.js +6 -0
- package/dist/messages-DJR8CYOj.js.map +1 -0
- package/dist/messages-DPQrkuU6.js +6 -0
- package/dist/messages-DPQrkuU6.js.map +1 -0
- package/dist/messages-DrynHX-x.js +6 -0
- package/dist/messages-DrynHX-x.js.map +1 -0
- package/dist/messages-DxvoH7IR.js +6 -0
- package/dist/messages-DxvoH7IR.js.map +1 -0
- package/dist/messages-GjCJvcKn.js +6 -0
- package/dist/messages-GjCJvcKn.js.map +1 -0
- package/dist/messages-SBH5be2k.js +6 -0
- package/dist/messages-SBH5be2k.js.map +1 -0
- package/dist/messages-b3mpa7MD.js +6 -0
- package/dist/messages-b3mpa7MD.js.map +1 -0
- package/dist/messages-rU-AKv73.js +6 -0
- package/dist/messages-rU-AKv73.js.map +1 -0
- package/dist/plugins-BPVhvih_.js.map +1 -1
- package/dist/portable-text-table.d.ts +144 -0
- package/dist/portable-text-table.d.ts.map +1 -0
- package/dist/portable-text-table.js +506 -0
- package/dist/portable-text-table.js.map +1 -0
- package/dist/styles.css +1 -1
- package/package.json +13 -5
- package/dist/LocaleDirectionProvider-DWBtquoB.js.map +0 -1
- package/dist/messages--4H_uJJx.js +0 -6
- package/dist/messages--4H_uJJx.js.map +0 -1
- package/dist/messages-1HW-Clzo.js +0 -6
- package/dist/messages-1HW-Clzo.js.map +0 -1
- package/dist/messages-3g7OPPLD.js +0 -6
- package/dist/messages-3g7OPPLD.js.map +0 -1
- package/dist/messages-3y7urMNZ.js +0 -6
- package/dist/messages-3y7urMNZ.js.map +0 -1
- package/dist/messages-Bi8Q6hQh.js +0 -6
- package/dist/messages-Bi8Q6hQh.js.map +0 -1
- package/dist/messages-C5M2v621.js +0 -6
- package/dist/messages-C5M2v621.js.map +0 -1
- package/dist/messages-CJVEZ_A5.js +0 -6
- package/dist/messages-CJVEZ_A5.js.map +0 -1
- package/dist/messages-CNbPYtov.js +0 -6
- package/dist/messages-CNbPYtov.js.map +0 -1
- package/dist/messages-CXOtPqxW.js +0 -6
- package/dist/messages-CXOtPqxW.js.map +0 -1
- package/dist/messages-CkNuItb-.js +0 -6
- package/dist/messages-CkNuItb-.js.map +0 -1
- package/dist/messages-ClabBphB.js +0 -6
- package/dist/messages-ClabBphB.js.map +0 -1
- package/dist/messages-Cqj_YnUc.js +0 -6
- package/dist/messages-Cqj_YnUc.js.map +0 -1
- package/dist/messages-Cy_HI78n.js +0 -6
- package/dist/messages-Cy_HI78n.js.map +0 -1
- package/dist/messages-D-WF9xWO.js +0 -6
- package/dist/messages-D-WF9xWO.js.map +0 -1
- package/dist/messages-D2cvoQzD.js +0 -6
- package/dist/messages-D2cvoQzD.js.map +0 -1
- package/dist/messages-DC8BlS4V.js +0 -6
- package/dist/messages-DC8BlS4V.js.map +0 -1
- package/dist/messages-DMQToQxw.js +0 -6
- package/dist/messages-DMQToQxw.js.map +0 -1
- package/dist/messages-DWBTgm-y.js +0 -6
- package/dist/messages-DWBTgm-y.js.map +0 -1
- package/dist/messages-DjoDBrf1.js +0 -6
- package/dist/messages-DjoDBrf1.js.map +0 -1
- package/dist/messages-Dkr-4VFi.js +0 -6
- package/dist/messages-Dkr-4VFi.js.map +0 -1
- package/dist/messages-DmQsSz7M.js +0 -6
- package/dist/messages-DmQsSz7M.js.map +0 -1
- package/dist/messages-Dnpi1ztm.js +0 -6
- package/dist/messages-Dnpi1ztm.js.map +0 -1
- package/dist/messages-OdBFlKpa.js +0 -6
- package/dist/messages-OdBFlKpa.js.map +0 -1
- package/dist/messages-RBIsUSWq.js +0 -6
- package/dist/messages-RBIsUSWq.js.map +0 -1
- package/dist/messages-_6oZo840.js +0 -6
- package/dist/messages-_6oZo840.js.map +0 -1
- package/dist/messages-kpo6a8yB.js +0 -6
- package/dist/messages-kpo6a8yB.js.map +0 -1
- package/dist/messages-oZUnGK0y.js +0 -6
- package/dist/messages-oZUnGK0y.js.map +0 -1
- package/dist/messages-u4KSs1DK.js +0 -6
- package/dist/messages-u4KSs1DK.js.map +0 -1
|
@@ -0,0 +1,506 @@
|
|
|
1
|
+
//#region src/portable-text-table.ts
|
|
2
|
+
const MAX_TABLE_SPAN = 100;
|
|
3
|
+
const MAX_TABLE_COLUMN_WIDTH = 4096;
|
|
4
|
+
const TABLE_CELL_MIN_WIDTH = 96;
|
|
5
|
+
const TABLE_COLUMN_WIDTH_STEP = 16;
|
|
6
|
+
const TABLE_RESIZE_HANDLE_WIDTH = 2;
|
|
7
|
+
const TABLE_RESIZE_TARGET_WIDTH = 24;
|
|
8
|
+
const MAX_TABLE_REPAIRED_SLOTS = 2e4;
|
|
9
|
+
const MAX_TABLE_PASTE_ROWS = 100;
|
|
10
|
+
const MAX_TABLE_PASTE_COLUMNS = 100;
|
|
11
|
+
const MAX_TABLE_PASTE_CELLS = 1e4;
|
|
12
|
+
const MAX_TABLE_PASTE_TEXT_BYTES = 1048576;
|
|
13
|
+
const MAX_TABLE_SOURCE_ENTRIES = MAX_TABLE_REPAIRED_SLOTS * 4;
|
|
14
|
+
var NormalizationFailure = class extends Error {
|
|
15
|
+
constructor(reason) {
|
|
16
|
+
super();
|
|
17
|
+
this.reason = reason;
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
const fail = (reason) => {
|
|
21
|
+
throw new NormalizationFailure(reason);
|
|
22
|
+
};
|
|
23
|
+
const DECORATOR_MARKS = new Set("strong em underline strike-through subscript superscript code".split(" "));
|
|
24
|
+
const TABLE_FIELDS = new Set("_type _key rows hasHeaderRow markDefs".split(" "));
|
|
25
|
+
const ROW_FIELDS = new Set("_type _key cells".split(" "));
|
|
26
|
+
const CELL_FIELDS = new Set("_type _key content markDefs isHeader colspan rowspan colwidth textAlign".split(" "));
|
|
27
|
+
const DOM_FIELD = /^(?:aria-|data-|class(?:name)?$|id$|role$|style$|on(?:animation(?:end|iteration|start)|beforeinput|blur|change|click|contextmenu|copy|cut|drag|drop|error|focus|input|key(?:down|press|up)|load|mouse(?:down|move|up)|paste|pointer(?:down|move|up)|scroll|submit|touch(?:end|move|start)|transition(?:cancel|end|run|start)|wheel)$)/i;
|
|
28
|
+
var UnsafePortableTextTableError = class extends Error {
|
|
29
|
+
code = "UNSAFE_PORTABLE_TEXT_TABLE";
|
|
30
|
+
constructor(reason, raw, renderFallback) {
|
|
31
|
+
super(`Unsafe Portable Text table: ${reason}`);
|
|
32
|
+
this.reason = reason;
|
|
33
|
+
this.raw = raw;
|
|
34
|
+
this.renderFallback = renderFallback;
|
|
35
|
+
this.name = "UnsafePortableTextTableError";
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
function isPortableTextTableInput(value) {
|
|
39
|
+
return isRecord(value) && value._type === "table";
|
|
40
|
+
}
|
|
41
|
+
function normalizePortableTextTable(value, context) {
|
|
42
|
+
return catchFailure(value, context, () => normalizeTable(value, context));
|
|
43
|
+
}
|
|
44
|
+
function normalizeTable(value, context) {
|
|
45
|
+
if (!isPortableTextTableInput(value) || value.rows !== void 0 && !Array.isArray(value.rows)) return fail("INVALID_TABLE");
|
|
46
|
+
const rawRows = Array.isArray(value.rows) ? value.rows : [];
|
|
47
|
+
let sourceCells = 0;
|
|
48
|
+
let sourceEntries = rawRows.length + (Array.isArray(value.markDefs) ? value.markDefs.length : 0);
|
|
49
|
+
for (const row of rawRows) {
|
|
50
|
+
if (!isRecord(row) || !Array.isArray(row.cells)) continue;
|
|
51
|
+
sourceCells += row.cells.length;
|
|
52
|
+
sourceEntries += row.cells.length;
|
|
53
|
+
for (const cell of row.cells) {
|
|
54
|
+
if (!isRecord(cell)) continue;
|
|
55
|
+
if (Array.isArray(cell.content)) sourceEntries += cell.content.length;
|
|
56
|
+
if (Array.isArray(cell.markDefs)) sourceEntries += cell.markDefs.length;
|
|
57
|
+
}
|
|
58
|
+
if (sourceCells > MAX_TABLE_REPAIRED_SLOTS || sourceEntries > MAX_TABLE_SOURCE_ENTRIES) return fail("TABLE_TOO_LARGE");
|
|
59
|
+
}
|
|
60
|
+
if (sourceEntries > MAX_TABLE_SOURCE_ENTRIES) return fail("TABLE_TOO_LARGE");
|
|
61
|
+
const seen = /* @__PURE__ */ new Set();
|
|
62
|
+
const tableKey = reserveKey(readKey(value._key) ?? legacyKey(`${context.path}:table`), seen);
|
|
63
|
+
const tableMarkDefs = normalizeMarkDefs(value.markDefs);
|
|
64
|
+
const tableMarks = indexMarkDefs(tableMarkDefs);
|
|
65
|
+
const firstContentRow = rawRows.findIndex((row) => isRecord(row) && Array.isArray(row.cells) && row.cells.length > 0);
|
|
66
|
+
const firstCells = firstContentRow >= 0 && isRecord(rawRows[firstContentRow]) ? rawRows[firstContentRow].cells : void 0;
|
|
67
|
+
const promoteHeader = value.hasHeaderRow === true && Array.isArray(firstCells) && !firstCells.some((cell) => isRecord(cell) && hasOwn(cell, "isHeader"));
|
|
68
|
+
const sourceRows = rawRows.map((rawRow, rowIndex) => {
|
|
69
|
+
const record = asRecord(rawRow);
|
|
70
|
+
const rowKey = reserveKey(readKey(record._key) ?? legacyKey(`${tableKey}:row:${rowIndex}`), seen);
|
|
71
|
+
const rawCells = Array.isArray(record.cells) ? record.cells : [];
|
|
72
|
+
return {
|
|
73
|
+
row: {
|
|
74
|
+
...safeFields(record, ROW_FIELDS),
|
|
75
|
+
_type: "tableRow",
|
|
76
|
+
_key: rowKey
|
|
77
|
+
},
|
|
78
|
+
cells: rawCells.map((cell, cellIndex) => normalizeCell(cell, {
|
|
79
|
+
path: `${rowKey}:cell:${cellIndex}`,
|
|
80
|
+
remainingRows: rawRows.length - rowIndex,
|
|
81
|
+
promoteHeader: promoteHeader && rowIndex === firstContentRow,
|
|
82
|
+
seen,
|
|
83
|
+
tableMarks
|
|
84
|
+
}))
|
|
85
|
+
};
|
|
86
|
+
});
|
|
87
|
+
if (!sourceRows.some((row) => row.cells.length > 0)) return {
|
|
88
|
+
ok: true,
|
|
89
|
+
table: tableFrom(value, tableKey, tableMarkDefs, [{
|
|
90
|
+
_type: "tableRow",
|
|
91
|
+
_key: reserveKey(legacyKey(`${tableKey}:repair-row:0`), seen),
|
|
92
|
+
cells: [emptyCell(reserveKey(legacyKey(`${tableKey}:repair-cell:0:0`), seen))]
|
|
93
|
+
}]),
|
|
94
|
+
width: 1,
|
|
95
|
+
height: 1
|
|
96
|
+
};
|
|
97
|
+
const height = sourceRows.length;
|
|
98
|
+
const occupied = Array.from({ length: height }, () => /* @__PURE__ */ new Set());
|
|
99
|
+
const placed = Array.from({ length: height }, () => []);
|
|
100
|
+
let width = 0;
|
|
101
|
+
for (let row = 0; row < height; row++) {
|
|
102
|
+
let cursor = 0;
|
|
103
|
+
for (const cell of sourceRows[row].cells) {
|
|
104
|
+
const colspan = cell.colspan ?? 1;
|
|
105
|
+
const rowspan = cell.rowspan ?? 1;
|
|
106
|
+
while (!rectangleFree(occupied, row, cursor, rowspan, colspan)) assertGridBound(++cursor + colspan, height);
|
|
107
|
+
assertGridBound(Math.max(width, cursor + colspan), height);
|
|
108
|
+
occupy(occupied, row, cursor, rowspan, colspan);
|
|
109
|
+
placed[row].push({
|
|
110
|
+
cell,
|
|
111
|
+
column: cursor
|
|
112
|
+
});
|
|
113
|
+
cursor += colspan;
|
|
114
|
+
width = Math.max(width, cursor);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
const columnWidths = Array.from({ length: width });
|
|
118
|
+
for (const row of placed) for (const { cell, column } of row) for (let offset = 0; offset < (cell.colspan ?? 1); offset++) {
|
|
119
|
+
const candidate = cell.colwidth?.[offset];
|
|
120
|
+
if (candidate && columnWidths[column + offset] === void 0) columnWidths[column + offset] = candidate;
|
|
121
|
+
}
|
|
122
|
+
const hasWidths = columnWidths.some((entry) => entry !== void 0);
|
|
123
|
+
if (hasWidths) for (let column = 0; column < width; column++) columnWidths[column] ??= TABLE_CELL_MIN_WIDTH;
|
|
124
|
+
const rows = sourceRows.map((source, rowIndex) => {
|
|
125
|
+
const anchors = new Map(placed[rowIndex].map(({ cell, column }) => [column, cell]));
|
|
126
|
+
const headers = source.cells.length > 0 && source.cells.every((cell) => cell.isHeader === true);
|
|
127
|
+
const cells = [];
|
|
128
|
+
for (let column = 0; column < width;) {
|
|
129
|
+
const anchored = anchors.get(column);
|
|
130
|
+
if (anchored) {
|
|
131
|
+
const span = anchored.colspan ?? 1;
|
|
132
|
+
cells.push(withWidths(anchored, column, span, columnWidths, hasWidths));
|
|
133
|
+
column += span;
|
|
134
|
+
} else if (occupied[rowIndex].has(column)) column++;
|
|
135
|
+
else {
|
|
136
|
+
const key = reserveKey(legacyKey(`${tableKey}:repair-cell:${rowIndex}:${column}`), seen);
|
|
137
|
+
cells.push(withWidths(emptyCell(key, headers), column++, 1, columnWidths, hasWidths));
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return {
|
|
141
|
+
...source.row,
|
|
142
|
+
cells
|
|
143
|
+
};
|
|
144
|
+
});
|
|
145
|
+
return {
|
|
146
|
+
ok: true,
|
|
147
|
+
table: tableFrom(value, tableKey, tableMarkDefs, rows, sourceRows[0].cells.length > 0 && rows[0].cells.every((cell) => cell.isHeader === true && (cell.rowspan ?? 1) === 1)),
|
|
148
|
+
width,
|
|
149
|
+
height
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
function portableTextTableToProseMirror(value, context) {
|
|
153
|
+
const normalized = normalizePortableTextTable(value, context);
|
|
154
|
+
if (!normalized.ok) return normalized;
|
|
155
|
+
const { table } = normalized;
|
|
156
|
+
const resolveCellMarkDefs = createPortableTextTableCellMarkResolver(table);
|
|
157
|
+
return {
|
|
158
|
+
ok: true,
|
|
159
|
+
width: normalized.width,
|
|
160
|
+
height: normalized.height,
|
|
161
|
+
node: {
|
|
162
|
+
type: "table",
|
|
163
|
+
attrs: pmAttrs(table, TABLE_FIELDS),
|
|
164
|
+
content: table.rows.map((row) => ({
|
|
165
|
+
type: "tableRow",
|
|
166
|
+
attrs: pmAttrs(row, ROW_FIELDS),
|
|
167
|
+
content: row.cells.map((cell) => ({
|
|
168
|
+
type: cell.isHeader ? "tableHeader" : "tableCell",
|
|
169
|
+
attrs: {
|
|
170
|
+
colspan: cell.colspan ?? 1,
|
|
171
|
+
rowspan: cell.rowspan ?? 1,
|
|
172
|
+
colwidth: cell.colwidth ?? null,
|
|
173
|
+
textAlign: cell.textAlign ?? null,
|
|
174
|
+
...pmAttrs(cell, CELL_FIELDS)
|
|
175
|
+
},
|
|
176
|
+
content: [{
|
|
177
|
+
type: "paragraph",
|
|
178
|
+
content: context.spansToInline(cell.content, resolveCellMarkDefs(cell))
|
|
179
|
+
}]
|
|
180
|
+
}))
|
|
181
|
+
}))
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
function proseMirrorTableToPortableText(value, context) {
|
|
186
|
+
return catchFailure(value, context, () => {
|
|
187
|
+
if (!isRecord(value) || value.type !== "table" || !Array.isArray(value.content)) return fail("INVALID_TABLE");
|
|
188
|
+
let sourceCells = 0;
|
|
189
|
+
let sourceEntries = value.content.length;
|
|
190
|
+
for (const row of value.content) {
|
|
191
|
+
if (!isRecord(row) || !Array.isArray(row.content)) continue;
|
|
192
|
+
sourceCells += row.content.length;
|
|
193
|
+
sourceEntries += row.content.length;
|
|
194
|
+
for (const cell of row.content) {
|
|
195
|
+
if (!isRecord(cell) || !Array.isArray(cell.content)) continue;
|
|
196
|
+
sourceEntries += cell.content.length;
|
|
197
|
+
for (const paragraph of cell.content) if (isRecord(paragraph) && Array.isArray(paragraph.content)) sourceEntries += paragraph.content.length;
|
|
198
|
+
}
|
|
199
|
+
if (sourceCells > MAX_TABLE_REPAIRED_SLOTS || sourceEntries > MAX_TABLE_SOURCE_ENTRIES) return fail("TABLE_TOO_LARGE");
|
|
200
|
+
}
|
|
201
|
+
const tableAttrs = asRecord(value.attrs);
|
|
202
|
+
const rows = value.content.map((row) => {
|
|
203
|
+
if (!isRecord(row) || row.type !== "tableRow" || !Array.isArray(row.content)) return fail("INVALID_TABLE");
|
|
204
|
+
const attrs = asRecord(row.attrs);
|
|
205
|
+
return {
|
|
206
|
+
...safeFields(attrs.emdashData),
|
|
207
|
+
_type: "tableRow",
|
|
208
|
+
_key: readKey(attrs.emdashKey) ?? context.createKey(),
|
|
209
|
+
cells: row.content.map((cell) => pmCell(cell, context))
|
|
210
|
+
};
|
|
211
|
+
});
|
|
212
|
+
return normalizeTable({
|
|
213
|
+
...safeFields(tableAttrs.emdashData),
|
|
214
|
+
_type: "table",
|
|
215
|
+
_key: readKey(tableAttrs.emdashKey) ?? context.createKey(),
|
|
216
|
+
rows
|
|
217
|
+
}, context);
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
function pmCell(value, context) {
|
|
221
|
+
if (!isRecord(value) || value.type !== "tableCell" && value.type !== "tableHeader" || !Array.isArray(value.content)) return fail("UNSUPPORTED_CELL_CONTENT");
|
|
222
|
+
const attrs = asRecord(value.attrs);
|
|
223
|
+
const content = [];
|
|
224
|
+
const markDefs = [];
|
|
225
|
+
for (let index = 0; index < value.content.length; index++) {
|
|
226
|
+
const paragraph = value.content[index];
|
|
227
|
+
if (!isRecord(paragraph) || paragraph.type !== "paragraph") return fail("UNSUPPORTED_CELL_CONTENT");
|
|
228
|
+
const inline = Array.isArray(paragraph.content) ? paragraph.content : [];
|
|
229
|
+
if (!inline.every((node) => isProseMirrorNode(node) && (node.type === "text" || node.type === "hardBreak"))) return fail("UNSUPPORTED_CELL_CONTENT");
|
|
230
|
+
const converted = context.inlineToSpans(inline);
|
|
231
|
+
if (index > 0) content.push({
|
|
232
|
+
_type: "span",
|
|
233
|
+
_key: context.createKey(),
|
|
234
|
+
text: "\n"
|
|
235
|
+
});
|
|
236
|
+
content.push(...converted.content);
|
|
237
|
+
markDefs.push(...converted.markDefs ?? []);
|
|
238
|
+
}
|
|
239
|
+
return {
|
|
240
|
+
...safeFields(attrs.emdashData),
|
|
241
|
+
_type: "tableCell",
|
|
242
|
+
_key: readKey(attrs.emdashKey) ?? context.createKey(),
|
|
243
|
+
content,
|
|
244
|
+
...markDefs.length > 0 ? { markDefs } : {},
|
|
245
|
+
isHeader: value.type === "tableHeader",
|
|
246
|
+
colspan: attrs.colspan,
|
|
247
|
+
rowspan: attrs.rowspan,
|
|
248
|
+
colwidth: attrs.colwidth,
|
|
249
|
+
textAlign: attrs.textAlign
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
function getPortableTextTableCellMarkDefs(table, cell) {
|
|
253
|
+
return getMarkDefs(table.markDefs ?? [], cell.markDefs ?? []);
|
|
254
|
+
}
|
|
255
|
+
function createPortableTextTableCellMarkResolver(table) {
|
|
256
|
+
const shared = indexMarkDefs(table.markDefs ?? []);
|
|
257
|
+
return (cell) => {
|
|
258
|
+
const local = indexMarkDefs(cell.markDefs ?? []);
|
|
259
|
+
const referenced = /* @__PURE__ */ new Map();
|
|
260
|
+
for (const span of cell.content) for (const key of span.marks ?? []) {
|
|
261
|
+
const definition = local.get(key) ?? shared.get(key);
|
|
262
|
+
if (definition) referenced.set(key, definition);
|
|
263
|
+
}
|
|
264
|
+
return [...referenced.values()];
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
function getPortableTextTableColumnWidths(table) {
|
|
268
|
+
const occupied = Array.from({ length: table.rows.length }, () => /* @__PURE__ */ new Set());
|
|
269
|
+
const widths = [];
|
|
270
|
+
for (let row = 0; row < table.rows.length; row++) {
|
|
271
|
+
let column = 0;
|
|
272
|
+
for (const cell of table.rows[row].cells) {
|
|
273
|
+
while (occupied[row].has(column)) column++;
|
|
274
|
+
const colspan = cell.colspan ?? 1;
|
|
275
|
+
for (let offset = 0; offset < colspan; offset++) {
|
|
276
|
+
const value = cell.colwidth?.[offset];
|
|
277
|
+
if (value && widths[column + offset] === void 0) widths[column + offset] = Math.max(TABLE_CELL_MIN_WIDTH, value);
|
|
278
|
+
}
|
|
279
|
+
occupy(occupied, row, column, cell.rowspan ?? 1, colspan);
|
|
280
|
+
column += colspan;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return widths.some(Boolean) ? widths.map((width) => width ?? TABLE_CELL_MIN_WIDTH) : void 0;
|
|
284
|
+
}
|
|
285
|
+
function normalizeCell(value, context) {
|
|
286
|
+
if (typeof value !== "string" && !isRecord(value)) return fail("UNSUPPORTED_CELL_CONTENT");
|
|
287
|
+
const record = asRecord(value);
|
|
288
|
+
const key = reserveKey(readKey(record._key) ?? legacyKey(context.path), context.seen);
|
|
289
|
+
const markDefs = normalizeMarkDefs(record.markDefs);
|
|
290
|
+
const localMarks = indexMarkDefs(markDefs);
|
|
291
|
+
const colspan = normalizeSpan(record.colspan);
|
|
292
|
+
const rowspan = Math.min(normalizeSpan(record.rowspan), Math.max(1, context.remainingRows));
|
|
293
|
+
const colwidth = normalizeColwidth(record.colwidth, colspan);
|
|
294
|
+
const textAlign = normalizeAlignment(record.textAlign);
|
|
295
|
+
const explicitHeader = hasOwn(record, "isHeader");
|
|
296
|
+
const isHeader = context.promoteHeader || record.isHeader === true ? true : explicitHeader && record.isHeader === false ? false : void 0;
|
|
297
|
+
const cell = {
|
|
298
|
+
...safeFields(record, CELL_FIELDS),
|
|
299
|
+
_type: "tableCell",
|
|
300
|
+
_key: key,
|
|
301
|
+
content: normalizeContent(value, record.content, key, (mark) => localMarks.get(mark) ?? context.tableMarks.get(mark))
|
|
302
|
+
};
|
|
303
|
+
if (markDefs.length > 0) cell.markDefs = markDefs;
|
|
304
|
+
if (isHeader !== void 0) cell.isHeader = isHeader;
|
|
305
|
+
if (colspan > 1) cell.colspan = colspan;
|
|
306
|
+
if (rowspan > 1) cell.rowspan = rowspan;
|
|
307
|
+
if (colwidth) cell.colwidth = colwidth;
|
|
308
|
+
if (textAlign) cell.textAlign = textAlign;
|
|
309
|
+
return cell;
|
|
310
|
+
}
|
|
311
|
+
function normalizeContent(rawCell, rawContent, cellKey, resolveMark) {
|
|
312
|
+
const fallbackSpan = (text) => ({
|
|
313
|
+
_type: "span",
|
|
314
|
+
_key: legacyKey(`${cellKey}:span:0`),
|
|
315
|
+
text
|
|
316
|
+
});
|
|
317
|
+
const values = typeof rawCell === "string" ? [fallbackSpan(rawCell)] : typeof rawContent === "string" ? [fallbackSpan(rawContent)] : rawContent === void 0 ? [] : rawContent;
|
|
318
|
+
if (!Array.isArray(values)) return fail("UNSUPPORTED_CELL_CONTENT");
|
|
319
|
+
const content = values.map((value, index) => {
|
|
320
|
+
if (!isRecord(value) || value._type !== "span" || typeof value.text !== "string") return fail("UNSUPPORTED_CELL_CONTENT");
|
|
321
|
+
const marks = value.marks ?? [];
|
|
322
|
+
if (!Array.isArray(marks)) return fail("UNSUPPORTED_MARK_DEFINITION");
|
|
323
|
+
const normalizedMarks = [];
|
|
324
|
+
for (const mark of marks) {
|
|
325
|
+
if (typeof mark !== "string" || !DECORATOR_MARKS.has(mark) && resolveMark(mark)?._type !== "link") return fail("UNSUPPORTED_MARK_DEFINITION");
|
|
326
|
+
normalizedMarks.push(mark);
|
|
327
|
+
}
|
|
328
|
+
return {
|
|
329
|
+
_type: "span",
|
|
330
|
+
_key: readKey(value._key) ?? legacyKey(`${cellKey}:span:${index}`),
|
|
331
|
+
text: value.text,
|
|
332
|
+
...normalizedMarks.length > 0 ? { marks: normalizedMarks } : {}
|
|
333
|
+
};
|
|
334
|
+
});
|
|
335
|
+
return content.length > 0 ? content : [emptySpan(cellKey)];
|
|
336
|
+
}
|
|
337
|
+
function normalizeMarkDefs(value) {
|
|
338
|
+
if (value === void 0) return [];
|
|
339
|
+
if (!Array.isArray(value)) return fail("UNSUPPORTED_MARK_DEFINITION");
|
|
340
|
+
return value.map((mark) => {
|
|
341
|
+
const key = isRecord(mark) ? readKey(mark._key) : void 0;
|
|
342
|
+
if (!isRecord(mark) || mark._type !== "link" || !key || typeof mark.href !== "string") return fail("UNSUPPORTED_MARK_DEFINITION");
|
|
343
|
+
return {
|
|
344
|
+
...safeFields(mark),
|
|
345
|
+
_type: "link",
|
|
346
|
+
_key: key
|
|
347
|
+
};
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
const normalizeSpan = (value) => typeof value === "number" && Number.isInteger(value) && value > 0 && value <= MAX_TABLE_SPAN ? value : 1;
|
|
351
|
+
function normalizeAlignment(value) {
|
|
352
|
+
return value === "left" || value === "center" || value === "right" || value === "justify" ? value : void 0;
|
|
353
|
+
}
|
|
354
|
+
function normalizeColwidth(value, colspan) {
|
|
355
|
+
if (!Array.isArray(value) || value.length !== colspan || !value.every(validWidth)) return void 0;
|
|
356
|
+
return value;
|
|
357
|
+
}
|
|
358
|
+
const validWidth = (value) => typeof value === "number" && Number.isInteger(value) && value >= 0 && value <= MAX_TABLE_COLUMN_WIDTH;
|
|
359
|
+
function assertGridBound(width, height) {
|
|
360
|
+
if (width * height > MAX_TABLE_REPAIRED_SLOTS) return fail("TABLE_TOO_LARGE");
|
|
361
|
+
}
|
|
362
|
+
function rectangleFree(occupied, row, column, rowspan, colspan) {
|
|
363
|
+
for (let y = row; y < row + rowspan; y++) for (let x = column; x < column + colspan; x++) if (occupied[y].has(x)) return false;
|
|
364
|
+
return true;
|
|
365
|
+
}
|
|
366
|
+
function occupy(occupied, row, column, rowspan, colspan) {
|
|
367
|
+
for (let y = row; y < row + rowspan; y++) for (let x = column; x < column + colspan; x++) occupied[y]?.add(x);
|
|
368
|
+
}
|
|
369
|
+
function withWidths(cell, column, colspan, widths, hasWidths) {
|
|
370
|
+
const { colwidth: _colwidth, ...rest } = cell;
|
|
371
|
+
if (!hasWidths) return rest;
|
|
372
|
+
return {
|
|
373
|
+
...rest,
|
|
374
|
+
colwidth: widths.slice(column, column + colspan).map((width) => width ?? TABLE_CELL_MIN_WIDTH)
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
function tableFrom(raw, key, markDefs, rows, hasHeaderRow = false) {
|
|
378
|
+
return {
|
|
379
|
+
...safeFields(raw, TABLE_FIELDS),
|
|
380
|
+
_type: "table",
|
|
381
|
+
_key: key,
|
|
382
|
+
rows,
|
|
383
|
+
...hasHeaderRow ? { hasHeaderRow: true } : {},
|
|
384
|
+
...markDefs.length > 0 ? { markDefs } : {}
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
const emptySpan = (key) => ({
|
|
388
|
+
_type: "span",
|
|
389
|
+
_key: legacyKey(`${key}:span:0`),
|
|
390
|
+
text: ""
|
|
391
|
+
});
|
|
392
|
+
function emptyCell(key, isHeader = false) {
|
|
393
|
+
return {
|
|
394
|
+
_type: "tableCell",
|
|
395
|
+
_key: key,
|
|
396
|
+
content: [emptySpan(key)],
|
|
397
|
+
...isHeader ? { isHeader: true } : {}
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
function catchFailure(raw, context, operation) {
|
|
401
|
+
try {
|
|
402
|
+
return operation();
|
|
403
|
+
} catch (error) {
|
|
404
|
+
if (error instanceof NormalizationFailure) return unsafeResult(error.reason, raw, context.path);
|
|
405
|
+
throw error;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
function unsafeResult(reason, raw, path) {
|
|
409
|
+
return {
|
|
410
|
+
ok: false,
|
|
411
|
+
reason,
|
|
412
|
+
raw,
|
|
413
|
+
...reason === "TABLE_TOO_LARGE" ? {} : { renderFallback: makeRenderFallback(raw, path) }
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
function makeRenderFallback(raw, path) {
|
|
417
|
+
const record = asRecord(raw);
|
|
418
|
+
const seen = /* @__PURE__ */ new Set();
|
|
419
|
+
const tableKey = reserveKey(readKey(record._key) ?? legacyKey(`${path}:fallback-table`), seen);
|
|
420
|
+
let remaining = MAX_TABLE_REPAIRED_SLOTS;
|
|
421
|
+
const rows = [];
|
|
422
|
+
for (const [rowIndex, rawRow] of (Array.isArray(record.rows) ? record.rows : []).entries()) {
|
|
423
|
+
const row = asRecord(rawRow);
|
|
424
|
+
const rawCells = Array.isArray(row.cells) ? row.cells : [];
|
|
425
|
+
if (Math.max(rawCells.length, 1) > remaining) return void 0;
|
|
426
|
+
const rowKey = reserveKey(readKey(row._key) ?? legacyKey(`${tableKey}:fallback-row:${rowIndex}`), seen);
|
|
427
|
+
const cells = rawCells.map((rawCell, cellIndex) => {
|
|
428
|
+
return fallbackCell(rawCell, reserveKey(readKey(asRecord(rawCell)._key) ?? legacyKey(`${rowKey}:fallback-cell:${cellIndex}`), seen));
|
|
429
|
+
});
|
|
430
|
+
if (cells.length === 0) cells.push(emptyCell(reserveKey(legacyKey(`${rowKey}:empty`), seen)));
|
|
431
|
+
remaining -= cells.length;
|
|
432
|
+
rows.push({
|
|
433
|
+
_type: "tableRow",
|
|
434
|
+
_key: rowKey,
|
|
435
|
+
cells
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
if (rows.length > 0) return {
|
|
439
|
+
_type: "table",
|
|
440
|
+
_key: tableKey,
|
|
441
|
+
rows
|
|
442
|
+
};
|
|
443
|
+
return {
|
|
444
|
+
_type: "table",
|
|
445
|
+
_key: tableKey,
|
|
446
|
+
rows: [{
|
|
447
|
+
_type: "tableRow",
|
|
448
|
+
_key: reserveKey(legacyKey(`${tableKey}:empty-row`), seen),
|
|
449
|
+
cells: [emptyCell(reserveKey(legacyKey(`${tableKey}:empty-cell`), seen))]
|
|
450
|
+
}]
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
const fallbackCell = (raw, key) => ({
|
|
454
|
+
_type: "tableCell",
|
|
455
|
+
_key: key,
|
|
456
|
+
content: [{
|
|
457
|
+
...emptySpan(key),
|
|
458
|
+
text: recoverText(raw)
|
|
459
|
+
}]
|
|
460
|
+
});
|
|
461
|
+
function recoverText(value, depth = 0) {
|
|
462
|
+
if (depth > 32) return "";
|
|
463
|
+
if (typeof value === "string") return value;
|
|
464
|
+
if (Array.isArray(value)) return value.map((entry) => recoverText(entry, depth + 1)).join("");
|
|
465
|
+
const record = asRecord(value);
|
|
466
|
+
if (typeof record.text === "string") return record.text;
|
|
467
|
+
if (typeof record.content === "string") return record.content;
|
|
468
|
+
return recoverText(Array.isArray(record.content) ? record.content : Array.isArray(record.children) ? record.children : [], depth + 1);
|
|
469
|
+
}
|
|
470
|
+
const indexMarkDefs = (marks) => new Map(marks.map((mark) => [mark._key, mark]));
|
|
471
|
+
function getMarkDefs(table, cell) {
|
|
472
|
+
const byKey = indexMarkDefs(table);
|
|
473
|
+
for (const mark of cell) byKey.set(mark._key, mark);
|
|
474
|
+
return [...byKey.values()];
|
|
475
|
+
}
|
|
476
|
+
function legacyKey(value) {
|
|
477
|
+
let hash = 2166136261;
|
|
478
|
+
for (let index = 0; index < value.length; index++) {
|
|
479
|
+
hash ^= value.charCodeAt(index);
|
|
480
|
+
hash = Math.imul(hash, 16777619);
|
|
481
|
+
}
|
|
482
|
+
return `legacy-table-${(hash >>> 0).toString(36)}`;
|
|
483
|
+
}
|
|
484
|
+
function reserveKey(base, seen) {
|
|
485
|
+
let candidate = base;
|
|
486
|
+
for (let suffix = 1; seen.has(candidate); suffix++) candidate = `${base}-${suffix}`;
|
|
487
|
+
seen.add(candidate);
|
|
488
|
+
return candidate;
|
|
489
|
+
}
|
|
490
|
+
const pmAttrs = (record, fields) => ({
|
|
491
|
+
emdashKey: record._key,
|
|
492
|
+
emdashData: safeFields(record, fields)
|
|
493
|
+
});
|
|
494
|
+
function safeFields(value, excluded = /* @__PURE__ */ new Set()) {
|
|
495
|
+
if (!isRecord(value)) return {};
|
|
496
|
+
return Object.fromEntries(Object.entries(value).filter(([key]) => !excluded.has(key) && key !== "__proto__" && key !== "prototype" && key !== "constructor" && !DOM_FIELD.test(key)));
|
|
497
|
+
}
|
|
498
|
+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
499
|
+
const asRecord = (value) => isRecord(value) ? value : {};
|
|
500
|
+
const readKey = (value) => typeof value === "string" && value.length > 0 ? value : void 0;
|
|
501
|
+
const hasOwn = (record, key) => Object.hasOwn(record, key);
|
|
502
|
+
const isProseMirrorNode = (value) => isRecord(value) && typeof value.type === "string";
|
|
503
|
+
|
|
504
|
+
//#endregion
|
|
505
|
+
export { MAX_TABLE_COLUMN_WIDTH, MAX_TABLE_PASTE_CELLS, MAX_TABLE_PASTE_COLUMNS, MAX_TABLE_PASTE_ROWS, MAX_TABLE_PASTE_TEXT_BYTES, MAX_TABLE_REPAIRED_SLOTS, MAX_TABLE_SPAN, TABLE_CELL_MIN_WIDTH, TABLE_COLUMN_WIDTH_STEP, TABLE_RESIZE_HANDLE_WIDTH, TABLE_RESIZE_TARGET_WIDTH, UnsafePortableTextTableError, createPortableTextTableCellMarkResolver, getPortableTextTableCellMarkDefs, getPortableTextTableColumnWidths, isPortableTextTableInput, normalizePortableTextTable, portableTextTableToProseMirror, proseMirrorTableToPortableText };
|
|
506
|
+
//# sourceMappingURL=portable-text-table.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"portable-text-table.js","names":[],"sources":["../src/portable-text-table.ts"],"sourcesContent":["export const MAX_TABLE_SPAN = 100;\nexport const MAX_TABLE_COLUMN_WIDTH = 4096;\nexport const TABLE_CELL_MIN_WIDTH = 96;\nexport const TABLE_COLUMN_WIDTH_STEP = 16;\nexport const TABLE_RESIZE_HANDLE_WIDTH = 2;\nexport const TABLE_RESIZE_TARGET_WIDTH = 24;\nexport const MAX_TABLE_REPAIRED_SLOTS = 20_000;\nexport const MAX_TABLE_PASTE_ROWS = 100;\nexport const MAX_TABLE_PASTE_COLUMNS = 100;\nexport const MAX_TABLE_PASTE_CELLS = 10_000;\nexport const MAX_TABLE_PASTE_TEXT_BYTES = 1_048_576;\nconst MAX_TABLE_SOURCE_ENTRIES = MAX_TABLE_REPAIRED_SLOTS * 4;\n\nexport type PortableTextTableAlignment = \"left\" | \"center\" | \"right\" | \"justify\";\n\nexport type PortableTextTableSpan = { _type: \"span\"; _key: string; text: string; marks?: string[] };\n\nexport type PortableTextTableMarkDef = { _type: string; _key: string; [key: string]: unknown };\n\nexport interface PortableTextTableCell {\n\t_type: \"tableCell\";\n\t_key: string;\n\tcontent: PortableTextTableSpan[];\n\tmarkDefs?: PortableTextTableMarkDef[];\n\tisHeader?: boolean;\n\tcolspan?: number;\n\trowspan?: number;\n\tcolwidth?: number[];\n\ttextAlign?: PortableTextTableAlignment;\n\t[key: string]: unknown;\n}\n\nexport interface PortableTextTableRow {\n\t_type: \"tableRow\";\n\t_key: string;\n\tcells: PortableTextTableCell[];\n\t[key: string]: unknown;\n}\n\nexport interface PortableTextTableBlock {\n\t_type: \"table\";\n\t_key: string;\n\trows: PortableTextTableRow[];\n\thasHeaderRow?: boolean;\n\tmarkDefs?: PortableTextTableMarkDef[];\n\t[key: string]: unknown;\n}\n\nexport interface PortableTextTableProseMirrorNode {\n\ttype: string;\n\tattrs?: Record<string, unknown>;\n\tcontent?: PortableTextTableProseMirrorNode[];\n\tmarks?: Array<{ type: string; attrs?: Record<string, unknown> }>;\n\ttext?: string;\n}\n\nexport type UnsafePortableTextTableReason =\n\t| \"INVALID_TABLE\"\n\t| \"TABLE_TOO_LARGE\"\n\t| \"UNSUPPORTED_CELL_CONTENT\"\n\t| \"UNSUPPORTED_MARK_DEFINITION\";\n\ntype PortableTextTableContext = { path: string; createKey: () => string };\n\ninterface PortableTextTableToProseMirrorContext extends PortableTextTableContext {\n\tspansToInline: (\n\t\tcontent: PortableTextTableSpan[],\n\t\tmarkDefs: PortableTextTableMarkDef[],\n\t) => PortableTextTableProseMirrorNode[];\n}\n\ninterface ProseMirrorTableToPortableTextContext extends PortableTextTableContext {\n\tinlineToSpans: (content: PortableTextTableProseMirrorNode[]) => {\n\t\tcontent: PortableTextTableSpan[];\n\t\tmarkDefs?: PortableTextTableMarkDef[];\n\t};\n}\n\ntype UnknownRecord = Record<string, unknown>;\ntype PlacedCell = { cell: PortableTextTableCell; column: number };\ntype SourceRow = {\n\trow: UnknownRecord & { _type: \"tableRow\"; _key: string };\n\tcells: PortableTextTableCell[];\n};\n\nclass NormalizationFailure extends Error {\n\tconstructor(readonly reason: UnsafePortableTextTableReason) {\n\t\tsuper();\n\t}\n}\n\nconst fail = (reason: UnsafePortableTextTableReason): never => {\n\tthrow new NormalizationFailure(reason);\n};\n\nconst DECORATOR_MARKS = new Set(\n\t\"strong em underline strike-through subscript superscript code\".split(\" \"),\n);\nconst TABLE_FIELDS = new Set(\"_type _key rows hasHeaderRow markDefs\".split(\" \"));\nconst ROW_FIELDS = new Set(\"_type _key cells\".split(\" \"));\nconst CELL_FIELDS = new Set(\n\t\"_type _key content markDefs isHeader colspan rowspan colwidth textAlign\".split(\" \"),\n);\nconst DOM_FIELD =\n\t/^(?:aria-|data-|class(?:name)?$|id$|role$|style$|on(?:animation(?:end|iteration|start)|beforeinput|blur|change|click|contextmenu|copy|cut|drag|drop|error|focus|input|key(?:down|press|up)|load|mouse(?:down|move|up)|paste|pointer(?:down|move|up)|scroll|submit|touch(?:end|move|start)|transition(?:cancel|end|run|start)|wheel)$)/i;\n\nexport class UnsafePortableTextTableError extends Error {\n\treadonly code = \"UNSAFE_PORTABLE_TEXT_TABLE\";\n\n\tconstructor(\n\t\treadonly reason: UnsafePortableTextTableReason,\n\t\treadonly raw: unknown,\n\t\treadonly renderFallback?: PortableTextTableBlock,\n\t) {\n\t\tsuper(`Unsafe Portable Text table: ${reason}`);\n\t\tthis.name = \"UnsafePortableTextTableError\";\n\t}\n}\n\nexport function isPortableTextTableInput(\n\tvalue: unknown,\n): value is UnknownRecord & { _type: \"table\" } {\n\treturn isRecord(value) && value._type === \"table\";\n}\n\nexport function normalizePortableTextTable(value: unknown, context: PortableTextTableContext) {\n\treturn catchFailure(value, context, () => normalizeTable(value, context));\n}\n\nfunction normalizeTable(value: unknown, context: PortableTextTableContext) {\n\tif (\n\t\t!isPortableTextTableInput(value) ||\n\t\t(value.rows !== undefined && !Array.isArray(value.rows))\n\t) {\n\t\treturn fail(\"INVALID_TABLE\");\n\t}\n\n\tconst rawRows = Array.isArray(value.rows) ? value.rows : [];\n\tlet sourceCells = 0;\n\tlet sourceEntries = rawRows.length + (Array.isArray(value.markDefs) ? value.markDefs.length : 0);\n\tfor (const row of rawRows) {\n\t\tif (!isRecord(row) || !Array.isArray(row.cells)) continue;\n\t\tsourceCells += row.cells.length;\n\t\tsourceEntries += row.cells.length;\n\t\tfor (const cell of row.cells) {\n\t\t\tif (!isRecord(cell)) continue;\n\t\t\tif (Array.isArray(cell.content)) sourceEntries += cell.content.length;\n\t\t\tif (Array.isArray(cell.markDefs)) sourceEntries += cell.markDefs.length;\n\t\t}\n\t\tif (sourceCells > MAX_TABLE_REPAIRED_SLOTS || sourceEntries > MAX_TABLE_SOURCE_ENTRIES) {\n\t\t\treturn fail(\"TABLE_TOO_LARGE\");\n\t\t}\n\t}\n\tif (sourceEntries > MAX_TABLE_SOURCE_ENTRIES) return fail(\"TABLE_TOO_LARGE\");\n\tconst seen = new Set<string>();\n\tconst tableKey = reserveKey(readKey(value._key) ?? legacyKey(`${context.path}:table`), seen);\n\tconst tableMarkDefs = normalizeMarkDefs(value.markDefs);\n\tconst tableMarks = indexMarkDefs(tableMarkDefs);\n\tconst firstContentRow = rawRows.findIndex(\n\t\t(row) => isRecord(row) && Array.isArray(row.cells) && row.cells.length > 0,\n\t);\n\tconst firstCells =\n\t\tfirstContentRow >= 0 && isRecord(rawRows[firstContentRow])\n\t\t\t? rawRows[firstContentRow].cells\n\t\t\t: undefined;\n\tconst promoteHeader =\n\t\tvalue.hasHeaderRow === true &&\n\t\tArray.isArray(firstCells) &&\n\t\t!firstCells.some((cell) => isRecord(cell) && hasOwn(cell, \"isHeader\"));\n\n\tconst sourceRows: SourceRow[] = rawRows.map((rawRow, rowIndex) => {\n\t\tconst record = asRecord(rawRow);\n\t\tconst rowKey = reserveKey(\n\t\t\treadKey(record._key) ?? legacyKey(`${tableKey}:row:${rowIndex}`),\n\t\t\tseen,\n\t\t);\n\t\tconst rawCells = Array.isArray(record.cells) ? record.cells : [];\n\t\treturn {\n\t\t\trow: { ...safeFields(record, ROW_FIELDS), _type: \"tableRow\", _key: rowKey },\n\t\t\tcells: rawCells.map((cell, cellIndex) =>\n\t\t\t\tnormalizeCell(cell, {\n\t\t\t\t\tpath: `${rowKey}:cell:${cellIndex}`,\n\t\t\t\t\tremainingRows: rawRows.length - rowIndex,\n\t\t\t\t\tpromoteHeader: promoteHeader && rowIndex === firstContentRow,\n\t\t\t\t\tseen,\n\t\t\t\t\ttableMarks,\n\t\t\t\t}),\n\t\t\t),\n\t\t};\n\t});\n\n\tif (!sourceRows.some((row) => row.cells.length > 0)) {\n\t\tconst rowKey = reserveKey(legacyKey(`${tableKey}:repair-row:0`), seen);\n\t\tconst cell = emptyCell(reserveKey(legacyKey(`${tableKey}:repair-cell:0:0`), seen));\n\t\treturn {\n\t\t\tok: true as const,\n\t\t\ttable: tableFrom(value, tableKey, tableMarkDefs, [\n\t\t\t\t{ _type: \"tableRow\", _key: rowKey, cells: [cell] },\n\t\t\t]),\n\t\t\twidth: 1,\n\t\t\theight: 1,\n\t\t};\n\t}\n\n\tconst height = sourceRows.length;\n\tconst occupied = Array.from({ length: height }, () => new Set<number>());\n\tconst placed = Array.from({ length: height }, () => [] as PlacedCell[]);\n\tlet width = 0;\n\tfor (let row = 0; row < height; row++) {\n\t\tlet cursor = 0;\n\t\tfor (const cell of sourceRows[row]!.cells) {\n\t\t\tconst colspan = cell.colspan ?? 1;\n\t\t\tconst rowspan = cell.rowspan ?? 1;\n\t\t\twhile (!rectangleFree(occupied, row, cursor, rowspan, colspan)) {\n\t\t\t\tassertGridBound(++cursor + colspan, height);\n\t\t\t}\n\t\t\tassertGridBound(Math.max(width, cursor + colspan), height);\n\t\t\toccupy(occupied, row, cursor, rowspan, colspan);\n\t\t\tplaced[row]!.push({ cell, column: cursor });\n\t\t\tcursor += colspan;\n\t\t\twidth = Math.max(width, cursor);\n\t\t}\n\t}\n\n\tconst columnWidths: Array<number | undefined> = Array.from({ length: width });\n\tfor (const row of placed) {\n\t\tfor (const { cell, column } of row) {\n\t\t\tfor (let offset = 0; offset < (cell.colspan ?? 1); offset++) {\n\t\t\t\tconst candidate = cell.colwidth?.[offset];\n\t\t\t\tif (candidate && columnWidths[column + offset] === undefined) {\n\t\t\t\t\tcolumnWidths[column + offset] = candidate;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tconst hasWidths = columnWidths.some((entry) => entry !== undefined);\n\tif (hasWidths) {\n\t\tfor (let column = 0; column < width; column++) columnWidths[column] ??= TABLE_CELL_MIN_WIDTH;\n\t}\n\n\tconst rows = sourceRows.map((source, rowIndex): PortableTextTableRow => {\n\t\tconst anchors = new Map(placed[rowIndex]!.map(({ cell, column }) => [column, cell]));\n\t\tconst headers = source.cells.length > 0 && source.cells.every((cell) => cell.isHeader === true);\n\t\tconst cells: PortableTextTableCell[] = [];\n\t\tfor (let column = 0; column < width;) {\n\t\t\tconst anchored = anchors.get(column);\n\t\t\tif (anchored) {\n\t\t\t\tconst span = anchored.colspan ?? 1;\n\t\t\t\tcells.push(withWidths(anchored, column, span, columnWidths, hasWidths));\n\t\t\t\tcolumn += span;\n\t\t\t} else if (occupied[rowIndex]!.has(column)) {\n\t\t\t\tcolumn++;\n\t\t\t} else {\n\t\t\t\tconst key = reserveKey(legacyKey(`${tableKey}:repair-cell:${rowIndex}:${column}`), seen);\n\t\t\t\tcells.push(withWidths(emptyCell(key, headers), column++, 1, columnWidths, hasWidths));\n\t\t\t}\n\t\t}\n\t\treturn { ...source.row, cells };\n\t});\n\tconst hasHeaderRow =\n\t\tsourceRows[0]!.cells.length > 0 &&\n\t\trows[0]!.cells.every((cell) => cell.isHeader === true && (cell.rowspan ?? 1) === 1);\n\treturn {\n\t\tok: true as const,\n\t\ttable: tableFrom(value, tableKey, tableMarkDefs, rows, hasHeaderRow),\n\t\twidth,\n\t\theight,\n\t};\n}\n\nexport function portableTextTableToProseMirror(\n\tvalue: unknown,\n\tcontext: PortableTextTableToProseMirrorContext,\n) {\n\tconst normalized = normalizePortableTextTable(value, context);\n\tif (!normalized.ok) return normalized;\n\tconst { table } = normalized;\n\tconst resolveCellMarkDefs = createPortableTextTableCellMarkResolver(table);\n\treturn {\n\t\tok: true as const,\n\t\twidth: normalized.width,\n\t\theight: normalized.height,\n\t\tnode: {\n\t\t\ttype: \"table\",\n\t\t\tattrs: pmAttrs(table, TABLE_FIELDS),\n\t\t\tcontent: table.rows.map((row) => ({\n\t\t\t\ttype: \"tableRow\",\n\t\t\t\tattrs: pmAttrs(row, ROW_FIELDS),\n\t\t\t\tcontent: row.cells.map((cell) => ({\n\t\t\t\t\ttype: cell.isHeader ? \"tableHeader\" : \"tableCell\",\n\t\t\t\t\tattrs: {\n\t\t\t\t\t\tcolspan: cell.colspan ?? 1,\n\t\t\t\t\t\trowspan: cell.rowspan ?? 1,\n\t\t\t\t\t\tcolwidth: cell.colwidth ?? null,\n\t\t\t\t\t\ttextAlign: cell.textAlign ?? null,\n\t\t\t\t\t\t...pmAttrs(cell, CELL_FIELDS),\n\t\t\t\t\t},\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"paragraph\",\n\t\t\t\t\t\t\tcontent: context.spansToInline(cell.content, resolveCellMarkDefs(cell)),\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t})),\n\t\t\t})),\n\t\t},\n\t};\n}\n\nexport function proseMirrorTableToPortableText(\n\tvalue: unknown,\n\tcontext: ProseMirrorTableToPortableTextContext,\n) {\n\treturn catchFailure(value, context, () => {\n\t\tif (!isRecord(value) || value.type !== \"table\" || !Array.isArray(value.content)) {\n\t\t\treturn fail(\"INVALID_TABLE\");\n\t\t}\n\t\tlet sourceCells = 0;\n\t\tlet sourceEntries = value.content.length;\n\t\tfor (const row of value.content) {\n\t\t\tif (!isRecord(row) || !Array.isArray(row.content)) continue;\n\t\t\tsourceCells += row.content.length;\n\t\t\tsourceEntries += row.content.length;\n\t\t\tfor (const cell of row.content) {\n\t\t\t\tif (!isRecord(cell) || !Array.isArray(cell.content)) continue;\n\t\t\t\tsourceEntries += cell.content.length;\n\t\t\t\tfor (const paragraph of cell.content) {\n\t\t\t\t\tif (isRecord(paragraph) && Array.isArray(paragraph.content)) {\n\t\t\t\t\t\tsourceEntries += paragraph.content.length;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (sourceCells > MAX_TABLE_REPAIRED_SLOTS || sourceEntries > MAX_TABLE_SOURCE_ENTRIES) {\n\t\t\t\treturn fail(\"TABLE_TOO_LARGE\");\n\t\t\t}\n\t\t}\n\t\tconst tableAttrs = asRecord(value.attrs);\n\t\tconst rows = value.content.map((row): UnknownRecord => {\n\t\t\tif (!isRecord(row) || row.type !== \"tableRow\" || !Array.isArray(row.content)) {\n\t\t\t\treturn fail(\"INVALID_TABLE\");\n\t\t\t}\n\t\t\tconst attrs = asRecord(row.attrs);\n\t\t\treturn {\n\t\t\t\t...safeFields(attrs.emdashData),\n\t\t\t\t_type: \"tableRow\",\n\t\t\t\t_key: readKey(attrs.emdashKey) ?? context.createKey(),\n\t\t\t\tcells: row.content.map((cell) => pmCell(cell, context)),\n\t\t\t};\n\t\t});\n\t\treturn normalizeTable(\n\t\t\t{\n\t\t\t\t...safeFields(tableAttrs.emdashData),\n\t\t\t\t_type: \"table\",\n\t\t\t\t_key: readKey(tableAttrs.emdashKey) ?? context.createKey(),\n\t\t\t\trows,\n\t\t\t},\n\t\t\tcontext,\n\t\t);\n\t});\n}\n\nfunction pmCell(value: unknown, context: ProseMirrorTableToPortableTextContext): UnknownRecord {\n\tif (\n\t\t!isRecord(value) ||\n\t\t(value.type !== \"tableCell\" && value.type !== \"tableHeader\") ||\n\t\t!Array.isArray(value.content)\n\t) {\n\t\treturn fail(\"UNSUPPORTED_CELL_CONTENT\");\n\t}\n\tconst attrs = asRecord(value.attrs);\n\tconst content: PortableTextTableSpan[] = [];\n\tconst markDefs: PortableTextTableMarkDef[] = [];\n\tfor (let index = 0; index < value.content.length; index++) {\n\t\tconst paragraph = value.content[index];\n\t\tif (!isRecord(paragraph) || paragraph.type !== \"paragraph\") {\n\t\t\treturn fail(\"UNSUPPORTED_CELL_CONTENT\");\n\t\t}\n\t\tconst inline = Array.isArray(paragraph.content) ? paragraph.content : [];\n\t\tif (\n\t\t\t!inline.every(\n\t\t\t\t(node) => isProseMirrorNode(node) && (node.type === \"text\" || node.type === \"hardBreak\"),\n\t\t\t)\n\t\t) {\n\t\t\treturn fail(\"UNSUPPORTED_CELL_CONTENT\");\n\t\t}\n\t\tconst converted = context.inlineToSpans(inline);\n\t\tif (index > 0) content.push({ _type: \"span\", _key: context.createKey(), text: \"\\n\" });\n\t\tcontent.push(...converted.content);\n\t\tmarkDefs.push(...(converted.markDefs ?? []));\n\t}\n\treturn {\n\t\t...safeFields(attrs.emdashData),\n\t\t_type: \"tableCell\",\n\t\t_key: readKey(attrs.emdashKey) ?? context.createKey(),\n\t\tcontent,\n\t\t...(markDefs.length > 0 ? { markDefs } : {}),\n\t\tisHeader: value.type === \"tableHeader\",\n\t\tcolspan: attrs.colspan,\n\t\trowspan: attrs.rowspan,\n\t\tcolwidth: attrs.colwidth,\n\t\ttextAlign: attrs.textAlign,\n\t};\n}\n\nexport function getPortableTextTableCellMarkDefs(\n\ttable: PortableTextTableBlock,\n\tcell: PortableTextTableCell,\n): PortableTextTableMarkDef[] {\n\treturn getMarkDefs(table.markDefs ?? [], cell.markDefs ?? []);\n}\n\nexport function createPortableTextTableCellMarkResolver(table: PortableTextTableBlock) {\n\tconst shared = indexMarkDefs(table.markDefs ?? []);\n\treturn (cell: PortableTextTableCell): PortableTextTableMarkDef[] => {\n\t\tconst local = indexMarkDefs(cell.markDefs ?? []);\n\t\tconst referenced = new Map<string, PortableTextTableMarkDef>();\n\t\tfor (const span of cell.content) {\n\t\t\tfor (const key of span.marks ?? []) {\n\t\t\t\tconst definition = local.get(key) ?? shared.get(key);\n\t\t\t\tif (definition) referenced.set(key, definition);\n\t\t\t}\n\t\t}\n\t\treturn [...referenced.values()];\n\t};\n}\n\nexport function getPortableTextTableColumnWidths(\n\ttable: PortableTextTableBlock,\n): number[] | undefined {\n\tconst occupied = Array.from({ length: table.rows.length }, () => new Set<number>());\n\tconst widths: Array<number | undefined> = [];\n\tfor (let row = 0; row < table.rows.length; row++) {\n\t\tlet column = 0;\n\t\tfor (const cell of table.rows[row]!.cells) {\n\t\t\twhile (occupied[row]!.has(column)) column++;\n\t\t\tconst colspan = cell.colspan ?? 1;\n\t\t\tfor (let offset = 0; offset < colspan; offset++) {\n\t\t\t\tconst value = cell.colwidth?.[offset];\n\t\t\t\tif (value && widths[column + offset] === undefined) {\n\t\t\t\t\twidths[column + offset] = Math.max(TABLE_CELL_MIN_WIDTH, value);\n\t\t\t\t}\n\t\t\t}\n\t\t\toccupy(occupied, row, column, cell.rowspan ?? 1, colspan);\n\t\t\tcolumn += colspan;\n\t\t}\n\t}\n\treturn widths.some(Boolean) ? widths.map((width) => width ?? TABLE_CELL_MIN_WIDTH) : undefined;\n}\n\nfunction normalizeCell(\n\tvalue: unknown,\n\tcontext: {\n\t\tpath: string;\n\t\tremainingRows: number;\n\t\tpromoteHeader: boolean;\n\t\tseen: Set<string>;\n\t\ttableMarks: ReadonlyMap<string, PortableTextTableMarkDef>;\n\t},\n): PortableTextTableCell {\n\tif (typeof value !== \"string\" && !isRecord(value)) return fail(\"UNSUPPORTED_CELL_CONTENT\");\n\tconst record = asRecord(value);\n\tconst key = reserveKey(readKey(record._key) ?? legacyKey(context.path), context.seen);\n\tconst markDefs = normalizeMarkDefs(record.markDefs);\n\tconst localMarks = indexMarkDefs(markDefs);\n\tconst colspan = normalizeSpan(record.colspan);\n\tconst rowspan = Math.min(normalizeSpan(record.rowspan), Math.max(1, context.remainingRows));\n\tconst colwidth = normalizeColwidth(record.colwidth, colspan);\n\tconst textAlign = normalizeAlignment(record.textAlign);\n\tconst explicitHeader = hasOwn(record, \"isHeader\");\n\tconst isHeader =\n\t\tcontext.promoteHeader || record.isHeader === true\n\t\t\t? true\n\t\t\t: explicitHeader && record.isHeader === false\n\t\t\t\t? false\n\t\t\t\t: undefined;\n\tconst cell: PortableTextTableCell = {\n\t\t...safeFields(record, CELL_FIELDS),\n\t\t_type: \"tableCell\",\n\t\t_key: key,\n\t\tcontent: normalizeContent(\n\t\t\tvalue,\n\t\t\trecord.content,\n\t\t\tkey,\n\t\t\t(mark) => localMarks.get(mark) ?? context.tableMarks.get(mark),\n\t\t),\n\t};\n\tif (markDefs.length > 0) cell.markDefs = markDefs;\n\tif (isHeader !== undefined) cell.isHeader = isHeader;\n\tif (colspan > 1) cell.colspan = colspan;\n\tif (rowspan > 1) cell.rowspan = rowspan;\n\tif (colwidth) cell.colwidth = colwidth;\n\tif (textAlign) cell.textAlign = textAlign;\n\treturn cell;\n}\n\nfunction normalizeContent(\n\trawCell: unknown,\n\trawContent: unknown,\n\tcellKey: string,\n\tresolveMark: (key: string) => PortableTextTableMarkDef | undefined,\n): PortableTextTableSpan[] {\n\tconst fallbackSpan = (text: string): UnknownRecord => ({\n\t\t_type: \"span\",\n\t\t_key: legacyKey(`${cellKey}:span:0`),\n\t\ttext,\n\t});\n\tconst values =\n\t\ttypeof rawCell === \"string\"\n\t\t\t? [fallbackSpan(rawCell)]\n\t\t\t: typeof rawContent === \"string\"\n\t\t\t\t? [fallbackSpan(rawContent)]\n\t\t\t\t: rawContent === undefined\n\t\t\t\t\t? []\n\t\t\t\t\t: rawContent;\n\tif (!Array.isArray(values)) return fail(\"UNSUPPORTED_CELL_CONTENT\");\n\tconst content = values.map((value, index): PortableTextTableSpan => {\n\t\tif (!isRecord(value) || value._type !== \"span\" || typeof value.text !== \"string\") {\n\t\t\treturn fail(\"UNSUPPORTED_CELL_CONTENT\");\n\t\t}\n\t\tconst marks = value.marks ?? [];\n\t\tif (!Array.isArray(marks)) return fail(\"UNSUPPORTED_MARK_DEFINITION\");\n\t\tconst normalizedMarks: string[] = [];\n\t\tfor (const mark of marks) {\n\t\t\tif (\n\t\t\t\ttypeof mark !== \"string\" ||\n\t\t\t\t(!DECORATOR_MARKS.has(mark) && resolveMark(mark)?._type !== \"link\")\n\t\t\t) {\n\t\t\t\treturn fail(\"UNSUPPORTED_MARK_DEFINITION\");\n\t\t\t}\n\t\t\tnormalizedMarks.push(mark);\n\t\t}\n\t\treturn {\n\t\t\t_type: \"span\",\n\t\t\t_key: readKey(value._key) ?? legacyKey(`${cellKey}:span:${index}`),\n\t\t\ttext: value.text,\n\t\t\t...(normalizedMarks.length > 0 ? { marks: normalizedMarks } : {}),\n\t\t};\n\t});\n\treturn content.length > 0 ? content : [emptySpan(cellKey)];\n}\n\nfunction normalizeMarkDefs(value: unknown): PortableTextTableMarkDef[] {\n\tif (value === undefined) return [];\n\tif (!Array.isArray(value)) return fail(\"UNSUPPORTED_MARK_DEFINITION\");\n\treturn value.map((mark): PortableTextTableMarkDef => {\n\t\tconst key = isRecord(mark) ? readKey(mark._key) : undefined;\n\t\tif (!isRecord(mark) || mark._type !== \"link\" || !key || typeof mark.href !== \"string\") {\n\t\t\treturn fail(\"UNSUPPORTED_MARK_DEFINITION\");\n\t\t}\n\t\treturn { ...safeFields(mark), _type: \"link\", _key: key };\n\t});\n}\n\nconst normalizeSpan = (value: unknown): number =>\n\ttypeof value === \"number\" && Number.isInteger(value) && value > 0 && value <= MAX_TABLE_SPAN\n\t\t? value\n\t\t: 1;\n\nfunction normalizeAlignment(value: unknown): PortableTextTableAlignment | undefined {\n\treturn value === \"left\" || value === \"center\" || value === \"right\" || value === \"justify\"\n\t\t? value\n\t\t: undefined;\n}\n\nfunction normalizeColwidth(value: unknown, colspan: number): number[] | undefined {\n\tif (!Array.isArray(value) || value.length !== colspan || !value.every(validWidth))\n\t\treturn undefined;\n\treturn value;\n}\n\nconst validWidth = (value: unknown): value is number =>\n\ttypeof value === \"number\" &&\n\tNumber.isInteger(value) &&\n\tvalue >= 0 &&\n\tvalue <= MAX_TABLE_COLUMN_WIDTH;\n\nfunction assertGridBound(width: number, height: number): void {\n\tif (width * height > MAX_TABLE_REPAIRED_SLOTS) return fail(\"TABLE_TOO_LARGE\");\n}\n\nfunction rectangleFree(\n\toccupied: Array<Set<number>>,\n\trow: number,\n\tcolumn: number,\n\trowspan: number,\n\tcolspan: number,\n): boolean {\n\tfor (let y = row; y < row + rowspan; y++) {\n\t\tfor (let x = column; x < column + colspan; x++) if (occupied[y]!.has(x)) return false;\n\t}\n\treturn true;\n}\n\nfunction occupy(\n\toccupied: Array<Set<number>>,\n\trow: number,\n\tcolumn: number,\n\trowspan: number,\n\tcolspan: number,\n): void {\n\tfor (let y = row; y < row + rowspan; y++) {\n\t\tfor (let x = column; x < column + colspan; x++) occupied[y]?.add(x);\n\t}\n}\n\nfunction withWidths(\n\tcell: PortableTextTableCell,\n\tcolumn: number,\n\tcolspan: number,\n\twidths: Array<number | undefined>,\n\thasWidths: boolean,\n): PortableTextTableCell {\n\tconst { colwidth: _colwidth, ...rest } = cell;\n\tif (!hasWidths) return rest;\n\treturn {\n\t\t...rest,\n\t\tcolwidth: widths.slice(column, column + colspan).map((width) => width ?? TABLE_CELL_MIN_WIDTH),\n\t};\n}\n\nfunction tableFrom(\n\traw: UnknownRecord,\n\tkey: string,\n\tmarkDefs: PortableTextTableMarkDef[],\n\trows: PortableTextTableRow[],\n\thasHeaderRow = false,\n): PortableTextTableBlock {\n\treturn {\n\t\t...safeFields(raw, TABLE_FIELDS),\n\t\t_type: \"table\",\n\t\t_key: key,\n\t\trows,\n\t\t...(hasHeaderRow ? { hasHeaderRow: true } : {}),\n\t\t...(markDefs.length > 0 ? { markDefs } : {}),\n\t};\n}\n\nconst emptySpan = (key: string): PortableTextTableSpan => ({\n\t_type: \"span\",\n\t_key: legacyKey(`${key}:span:0`),\n\ttext: \"\",\n});\n\nfunction emptyCell(key: string, isHeader = false): PortableTextTableCell {\n\treturn {\n\t\t_type: \"tableCell\",\n\t\t_key: key,\n\t\tcontent: [emptySpan(key)],\n\t\t...(isHeader ? { isHeader: true } : {}),\n\t};\n}\n\nfunction catchFailure<T>(\n\traw: unknown,\n\tcontext: PortableTextTableContext,\n\toperation: () => T,\n): T | ReturnType<typeof unsafeResult> {\n\ttry {\n\t\treturn operation();\n\t} catch (error) {\n\t\tif (error instanceof NormalizationFailure) return unsafeResult(error.reason, raw, context.path);\n\t\tthrow error;\n\t}\n}\n\nfunction unsafeResult(reason: UnsafePortableTextTableReason, raw: unknown, path: string) {\n\treturn {\n\t\tok: false as const,\n\t\treason,\n\t\traw,\n\t\t...(reason === \"TABLE_TOO_LARGE\" ? {} : { renderFallback: makeRenderFallback(raw, path) }),\n\t};\n}\n\nfunction makeRenderFallback(raw: unknown, path: string): PortableTextTableBlock | undefined {\n\tconst record = asRecord(raw);\n\tconst seen = new Set<string>();\n\tconst tableKey = reserveKey(readKey(record._key) ?? legacyKey(`${path}:fallback-table`), seen);\n\tlet remaining = MAX_TABLE_REPAIRED_SLOTS;\n\tconst rows: PortableTextTableRow[] = [];\n\tfor (const [rowIndex, rawRow] of (Array.isArray(record.rows) ? record.rows : []).entries()) {\n\t\tconst row = asRecord(rawRow);\n\t\tconst rawCells = Array.isArray(row.cells) ? row.cells : [];\n\t\tif (Math.max(rawCells.length, 1) > remaining) return undefined;\n\t\tconst rowKey = reserveKey(\n\t\t\treadKey(row._key) ?? legacyKey(`${tableKey}:fallback-row:${rowIndex}`),\n\t\t\tseen,\n\t\t);\n\t\tconst cells = rawCells.map((rawCell, cellIndex): PortableTextTableCell => {\n\t\t\tconst cell = asRecord(rawCell);\n\t\t\tconst key = reserveKey(\n\t\t\t\treadKey(cell._key) ?? legacyKey(`${rowKey}:fallback-cell:${cellIndex}`),\n\t\t\t\tseen,\n\t\t\t);\n\t\t\treturn fallbackCell(rawCell, key);\n\t\t});\n\t\tif (cells.length === 0) {\n\t\t\tcells.push(emptyCell(reserveKey(legacyKey(`${rowKey}:empty`), seen)));\n\t\t}\n\t\tremaining -= cells.length;\n\t\trows.push({ _type: \"tableRow\", _key: rowKey, cells });\n\t}\n\tif (rows.length > 0) return { _type: \"table\", _key: tableKey, rows };\n\tconst rowKey = reserveKey(legacyKey(`${tableKey}:empty-row`), seen);\n\treturn {\n\t\t_type: \"table\",\n\t\t_key: tableKey,\n\t\trows: [\n\t\t\t{\n\t\t\t\t_type: \"tableRow\",\n\t\t\t\t_key: rowKey,\n\t\t\t\tcells: [emptyCell(reserveKey(legacyKey(`${tableKey}:empty-cell`), seen))],\n\t\t\t},\n\t\t],\n\t};\n}\n\nconst fallbackCell = (raw: unknown, key: string): PortableTextTableCell => ({\n\t_type: \"tableCell\",\n\t_key: key,\n\tcontent: [{ ...emptySpan(key), text: recoverText(raw) }],\n});\n\nfunction recoverText(value: unknown, depth = 0): string {\n\tif (depth > 32) return \"\";\n\tif (typeof value === \"string\") return value;\n\tif (Array.isArray(value)) return value.map((entry) => recoverText(entry, depth + 1)).join(\"\");\n\tconst record = asRecord(value);\n\tif (typeof record.text === \"string\") return record.text;\n\tif (typeof record.content === \"string\") return record.content;\n\tconst nested = Array.isArray(record.content)\n\t\t? record.content\n\t\t: Array.isArray(record.children)\n\t\t\t? record.children\n\t\t\t: [];\n\treturn recoverText(nested, depth + 1);\n}\n\nconst indexMarkDefs = (marks: PortableTextTableMarkDef[]) =>\n\tnew Map(marks.map((mark) => [mark._key, mark]));\n\nfunction getMarkDefs(\n\ttable: PortableTextTableMarkDef[],\n\tcell: PortableTextTableMarkDef[],\n): PortableTextTableMarkDef[] {\n\tconst byKey = indexMarkDefs(table);\n\tfor (const mark of cell) byKey.set(mark._key, mark);\n\treturn [...byKey.values()];\n}\n\nfunction legacyKey(value: string): string {\n\tlet hash = 0x811c9dc5;\n\tfor (let index = 0; index < value.length; index++) {\n\t\thash ^= value.charCodeAt(index);\n\t\thash = Math.imul(hash, 0x01000193);\n\t}\n\treturn `legacy-table-${(hash >>> 0).toString(36)}`;\n}\n\nfunction reserveKey(base: string, seen: Set<string>): string {\n\tlet candidate = base;\n\tfor (let suffix = 1; seen.has(candidate); suffix++) candidate = `${base}-${suffix}`;\n\tseen.add(candidate);\n\treturn candidate;\n}\n\nconst pmAttrs = (record: UnknownRecord, fields: Set<string>): UnknownRecord => ({\n\temdashKey: record._key,\n\temdashData: safeFields(record, fields),\n});\n\nfunction safeFields(value: unknown, excluded = new Set<string>()): UnknownRecord {\n\tif (!isRecord(value)) return {};\n\treturn Object.fromEntries(\n\t\tObject.entries(value).filter(\n\t\t\t([key]) =>\n\t\t\t\t!excluded.has(key) &&\n\t\t\t\tkey !== \"__proto__\" &&\n\t\t\t\tkey !== \"prototype\" &&\n\t\t\t\tkey !== \"constructor\" &&\n\t\t\t\t!DOM_FIELD.test(key),\n\t\t),\n\t);\n}\n\nconst isRecord = (value: unknown): value is UnknownRecord =>\n\ttypeof value === \"object\" && value !== null && !Array.isArray(value);\nconst asRecord = (value: unknown): UnknownRecord => (isRecord(value) ? value : {});\nconst readKey = (value: unknown): string | undefined =>\n\ttypeof value === \"string\" && value.length > 0 ? value : undefined;\nconst hasOwn = (record: UnknownRecord, key: string): boolean => Object.hasOwn(record, key);\nconst isProseMirrorNode = (value: unknown): value is PortableTextTableProseMirrorNode =>\n\tisRecord(value) && typeof value.type === \"string\";\n"],"mappings":";AAAA,MAAa,iBAAiB;AAC9B,MAAa,yBAAyB;AACtC,MAAa,uBAAuB;AACpC,MAAa,0BAA0B;AACvC,MAAa,4BAA4B;AACzC,MAAa,4BAA4B;AACzC,MAAa,2BAA2B;AACxC,MAAa,uBAAuB;AACpC,MAAa,0BAA0B;AACvC,MAAa,wBAAwB;AACrC,MAAa,6BAA6B;AAC1C,MAAM,2BAA2B,2BAA2B;AA0E5D,IAAM,uBAAN,cAAmC,MAAM;CACxC,YAAY,AAAS,QAAuC;AAC3D,SAAO;EADa;;;AAKtB,MAAM,QAAQ,WAAiD;AAC9D,OAAM,IAAI,qBAAqB,OAAO;;AAGvC,MAAM,kBAAkB,IAAI,IAC3B,gEAAgE,MAAM,IAAI,CAC1E;AACD,MAAM,eAAe,IAAI,IAAI,wCAAwC,MAAM,IAAI,CAAC;AAChF,MAAM,aAAa,IAAI,IAAI,mBAAmB,MAAM,IAAI,CAAC;AACzD,MAAM,cAAc,IAAI,IACvB,0EAA0E,MAAM,IAAI,CACpF;AACD,MAAM,YACL;AAED,IAAa,+BAAb,cAAkD,MAAM;CACvD,AAAS,OAAO;CAEhB,YACC,AAAS,QACT,AAAS,KACT,AAAS,gBACR;AACD,QAAM,+BAA+B,SAAS;EAJrC;EACA;EACA;AAGT,OAAK,OAAO;;;AAId,SAAgB,yBACf,OAC8C;AAC9C,QAAO,SAAS,MAAM,IAAI,MAAM,UAAU;;AAG3C,SAAgB,2BAA2B,OAAgB,SAAmC;AAC7F,QAAO,aAAa,OAAO,eAAe,eAAe,OAAO,QAAQ,CAAC;;AAG1E,SAAS,eAAe,OAAgB,SAAmC;AAC1E,KACC,CAAC,yBAAyB,MAAM,IAC/B,MAAM,SAAS,UAAa,CAAC,MAAM,QAAQ,MAAM,KAAK,CAEvD,QAAO,KAAK,gBAAgB;CAG7B,MAAM,UAAU,MAAM,QAAQ,MAAM,KAAK,GAAG,MAAM,OAAO,EAAE;CAC3D,IAAI,cAAc;CAClB,IAAI,gBAAgB,QAAQ,UAAU,MAAM,QAAQ,MAAM,SAAS,GAAG,MAAM,SAAS,SAAS;AAC9F,MAAK,MAAM,OAAO,SAAS;AAC1B,MAAI,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM,QAAQ,IAAI,MAAM,CAAE;AACjD,iBAAe,IAAI,MAAM;AACzB,mBAAiB,IAAI,MAAM;AAC3B,OAAK,MAAM,QAAQ,IAAI,OAAO;AAC7B,OAAI,CAAC,SAAS,KAAK,CAAE;AACrB,OAAI,MAAM,QAAQ,KAAK,QAAQ,CAAE,kBAAiB,KAAK,QAAQ;AAC/D,OAAI,MAAM,QAAQ,KAAK,SAAS,CAAE,kBAAiB,KAAK,SAAS;;AAElE,MAAI,cAAc,4BAA4B,gBAAgB,yBAC7D,QAAO,KAAK,kBAAkB;;AAGhC,KAAI,gBAAgB,yBAA0B,QAAO,KAAK,kBAAkB;CAC5E,MAAM,uBAAO,IAAI,KAAa;CAC9B,MAAM,WAAW,WAAW,QAAQ,MAAM,KAAK,IAAI,UAAU,GAAG,QAAQ,KAAK,QAAQ,EAAE,KAAK;CAC5F,MAAM,gBAAgB,kBAAkB,MAAM,SAAS;CACvD,MAAM,aAAa,cAAc,cAAc;CAC/C,MAAM,kBAAkB,QAAQ,WAC9B,QAAQ,SAAS,IAAI,IAAI,MAAM,QAAQ,IAAI,MAAM,IAAI,IAAI,MAAM,SAAS,EACzE;CACD,MAAM,aACL,mBAAmB,KAAK,SAAS,QAAQ,iBAAiB,GACvD,QAAQ,iBAAiB,QACzB;CACJ,MAAM,gBACL,MAAM,iBAAiB,QACvB,MAAM,QAAQ,WAAW,IACzB,CAAC,WAAW,MAAM,SAAS,SAAS,KAAK,IAAI,OAAO,MAAM,WAAW,CAAC;CAEvE,MAAM,aAA0B,QAAQ,KAAK,QAAQ,aAAa;EACjE,MAAM,SAAS,SAAS,OAAO;EAC/B,MAAM,SAAS,WACd,QAAQ,OAAO,KAAK,IAAI,UAAU,GAAG,SAAS,OAAO,WAAW,EAChE,KACA;EACD,MAAM,WAAW,MAAM,QAAQ,OAAO,MAAM,GAAG,OAAO,QAAQ,EAAE;AAChE,SAAO;GACN,KAAK;IAAE,GAAG,WAAW,QAAQ,WAAW;IAAE,OAAO;IAAY,MAAM;IAAQ;GAC3E,OAAO,SAAS,KAAK,MAAM,cAC1B,cAAc,MAAM;IACnB,MAAM,GAAG,OAAO,QAAQ;IACxB,eAAe,QAAQ,SAAS;IAChC,eAAe,iBAAiB,aAAa;IAC7C;IACA;IACA,CAAC,CACF;GACD;GACA;AAEF,KAAI,CAAC,WAAW,MAAM,QAAQ,IAAI,MAAM,SAAS,EAAE,CAGlD,QAAO;EACN,IAAI;EACJ,OAAO,UAAU,OAAO,UAAU,eAAe,CAChD;GAAE,OAAO;GAAY,MALR,WAAW,UAAU,GAAG,SAAS,eAAe,EAAE,KAAK;GAKjC,OAAO,CAJ/B,UAAU,WAAW,UAAU,GAAG,SAAS,kBAAkB,EAAE,KAAK,CAAC,CAIhC;GAAE,CAClD,CAAC;EACF,OAAO;EACP,QAAQ;EACR;CAGF,MAAM,SAAS,WAAW;CAC1B,MAAM,WAAW,MAAM,KAAK,EAAE,QAAQ,QAAQ,wBAAQ,IAAI,KAAa,CAAC;CACxE,MAAM,SAAS,MAAM,KAAK,EAAE,QAAQ,QAAQ,QAAQ,EAAE,CAAiB;CACvE,IAAI,QAAQ;AACZ,MAAK,IAAI,MAAM,GAAG,MAAM,QAAQ,OAAO;EACtC,IAAI,SAAS;AACb,OAAK,MAAM,QAAQ,WAAW,KAAM,OAAO;GAC1C,MAAM,UAAU,KAAK,WAAW;GAChC,MAAM,UAAU,KAAK,WAAW;AAChC,UAAO,CAAC,cAAc,UAAU,KAAK,QAAQ,SAAS,QAAQ,CAC7D,iBAAgB,EAAE,SAAS,SAAS,OAAO;AAE5C,mBAAgB,KAAK,IAAI,OAAO,SAAS,QAAQ,EAAE,OAAO;AAC1D,UAAO,UAAU,KAAK,QAAQ,SAAS,QAAQ;AAC/C,UAAO,KAAM,KAAK;IAAE;IAAM,QAAQ;IAAQ,CAAC;AAC3C,aAAU;AACV,WAAQ,KAAK,IAAI,OAAO,OAAO;;;CAIjC,MAAM,eAA0C,MAAM,KAAK,EAAE,QAAQ,OAAO,CAAC;AAC7E,MAAK,MAAM,OAAO,OACjB,MAAK,MAAM,EAAE,MAAM,YAAY,IAC9B,MAAK,IAAI,SAAS,GAAG,UAAU,KAAK,WAAW,IAAI,UAAU;EAC5D,MAAM,YAAY,KAAK,WAAW;AAClC,MAAI,aAAa,aAAa,SAAS,YAAY,OAClD,cAAa,SAAS,UAAU;;CAKpC,MAAM,YAAY,aAAa,MAAM,UAAU,UAAU,OAAU;AACnE,KAAI,UACH,MAAK,IAAI,SAAS,GAAG,SAAS,OAAO,SAAU,cAAa,YAAY;CAGzE,MAAM,OAAO,WAAW,KAAK,QAAQ,aAAmC;EACvE,MAAM,UAAU,IAAI,IAAI,OAAO,UAAW,KAAK,EAAE,MAAM,aAAa,CAAC,QAAQ,KAAK,CAAC,CAAC;EACpF,MAAM,UAAU,OAAO,MAAM,SAAS,KAAK,OAAO,MAAM,OAAO,SAAS,KAAK,aAAa,KAAK;EAC/F,MAAM,QAAiC,EAAE;AACzC,OAAK,IAAI,SAAS,GAAG,SAAS,QAAQ;GACrC,MAAM,WAAW,QAAQ,IAAI,OAAO;AACpC,OAAI,UAAU;IACb,MAAM,OAAO,SAAS,WAAW;AACjC,UAAM,KAAK,WAAW,UAAU,QAAQ,MAAM,cAAc,UAAU,CAAC;AACvE,cAAU;cACA,SAAS,UAAW,IAAI,OAAO,CACzC;QACM;IACN,MAAM,MAAM,WAAW,UAAU,GAAG,SAAS,eAAe,SAAS,GAAG,SAAS,EAAE,KAAK;AACxF,UAAM,KAAK,WAAW,UAAU,KAAK,QAAQ,EAAE,UAAU,GAAG,cAAc,UAAU,CAAC;;;AAGvF,SAAO;GAAE,GAAG,OAAO;GAAK;GAAO;GAC9B;AAIF,QAAO;EACN,IAAI;EACJ,OAAO,UAAU,OAAO,UAAU,eAAe,MAJjD,WAAW,GAAI,MAAM,SAAS,KAC9B,KAAK,GAAI,MAAM,OAAO,SAAS,KAAK,aAAa,SAAS,KAAK,WAAW,OAAO,EAAE,CAGf;EACpE;EACA;EACA;;AAGF,SAAgB,+BACf,OACA,SACC;CACD,MAAM,aAAa,2BAA2B,OAAO,QAAQ;AAC7D,KAAI,CAAC,WAAW,GAAI,QAAO;CAC3B,MAAM,EAAE,UAAU;CAClB,MAAM,sBAAsB,wCAAwC,MAAM;AAC1E,QAAO;EACN,IAAI;EACJ,OAAO,WAAW;EAClB,QAAQ,WAAW;EACnB,MAAM;GACL,MAAM;GACN,OAAO,QAAQ,OAAO,aAAa;GACnC,SAAS,MAAM,KAAK,KAAK,SAAS;IACjC,MAAM;IACN,OAAO,QAAQ,KAAK,WAAW;IAC/B,SAAS,IAAI,MAAM,KAAK,UAAU;KACjC,MAAM,KAAK,WAAW,gBAAgB;KACtC,OAAO;MACN,SAAS,KAAK,WAAW;MACzB,SAAS,KAAK,WAAW;MACzB,UAAU,KAAK,YAAY;MAC3B,WAAW,KAAK,aAAa;MAC7B,GAAG,QAAQ,MAAM,YAAY;MAC7B;KACD,SAAS,CACR;MACC,MAAM;MACN,SAAS,QAAQ,cAAc,KAAK,SAAS,oBAAoB,KAAK,CAAC;MACvE,CACD;KACD,EAAE;IACH,EAAE;GACH;EACD;;AAGF,SAAgB,+BACf,OACA,SACC;AACD,QAAO,aAAa,OAAO,eAAe;AACzC,MAAI,CAAC,SAAS,MAAM,IAAI,MAAM,SAAS,WAAW,CAAC,MAAM,QAAQ,MAAM,QAAQ,CAC9E,QAAO,KAAK,gBAAgB;EAE7B,IAAI,cAAc;EAClB,IAAI,gBAAgB,MAAM,QAAQ;AAClC,OAAK,MAAM,OAAO,MAAM,SAAS;AAChC,OAAI,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM,QAAQ,IAAI,QAAQ,CAAE;AACnD,kBAAe,IAAI,QAAQ;AAC3B,oBAAiB,IAAI,QAAQ;AAC7B,QAAK,MAAM,QAAQ,IAAI,SAAS;AAC/B,QAAI,CAAC,SAAS,KAAK,IAAI,CAAC,MAAM,QAAQ,KAAK,QAAQ,CAAE;AACrD,qBAAiB,KAAK,QAAQ;AAC9B,SAAK,MAAM,aAAa,KAAK,QAC5B,KAAI,SAAS,UAAU,IAAI,MAAM,QAAQ,UAAU,QAAQ,CAC1D,kBAAiB,UAAU,QAAQ;;AAItC,OAAI,cAAc,4BAA4B,gBAAgB,yBAC7D,QAAO,KAAK,kBAAkB;;EAGhC,MAAM,aAAa,SAAS,MAAM,MAAM;EACxC,MAAM,OAAO,MAAM,QAAQ,KAAK,QAAuB;AACtD,OAAI,CAAC,SAAS,IAAI,IAAI,IAAI,SAAS,cAAc,CAAC,MAAM,QAAQ,IAAI,QAAQ,CAC3E,QAAO,KAAK,gBAAgB;GAE7B,MAAM,QAAQ,SAAS,IAAI,MAAM;AACjC,UAAO;IACN,GAAG,WAAW,MAAM,WAAW;IAC/B,OAAO;IACP,MAAM,QAAQ,MAAM,UAAU,IAAI,QAAQ,WAAW;IACrD,OAAO,IAAI,QAAQ,KAAK,SAAS,OAAO,MAAM,QAAQ,CAAC;IACvD;IACA;AACF,SAAO,eACN;GACC,GAAG,WAAW,WAAW,WAAW;GACpC,OAAO;GACP,MAAM,QAAQ,WAAW,UAAU,IAAI,QAAQ,WAAW;GAC1D;GACA,EACD,QACA;GACA;;AAGH,SAAS,OAAO,OAAgB,SAA+D;AAC9F,KACC,CAAC,SAAS,MAAM,IACf,MAAM,SAAS,eAAe,MAAM,SAAS,iBAC9C,CAAC,MAAM,QAAQ,MAAM,QAAQ,CAE7B,QAAO,KAAK,2BAA2B;CAExC,MAAM,QAAQ,SAAS,MAAM,MAAM;CACnC,MAAM,UAAmC,EAAE;CAC3C,MAAM,WAAuC,EAAE;AAC/C,MAAK,IAAI,QAAQ,GAAG,QAAQ,MAAM,QAAQ,QAAQ,SAAS;EAC1D,MAAM,YAAY,MAAM,QAAQ;AAChC,MAAI,CAAC,SAAS,UAAU,IAAI,UAAU,SAAS,YAC9C,QAAO,KAAK,2BAA2B;EAExC,MAAM,SAAS,MAAM,QAAQ,UAAU,QAAQ,GAAG,UAAU,UAAU,EAAE;AACxE,MACC,CAAC,OAAO,OACN,SAAS,kBAAkB,KAAK,KAAK,KAAK,SAAS,UAAU,KAAK,SAAS,aAC5E,CAED,QAAO,KAAK,2BAA2B;EAExC,MAAM,YAAY,QAAQ,cAAc,OAAO;AAC/C,MAAI,QAAQ,EAAG,SAAQ,KAAK;GAAE,OAAO;GAAQ,MAAM,QAAQ,WAAW;GAAE,MAAM;GAAM,CAAC;AACrF,UAAQ,KAAK,GAAG,UAAU,QAAQ;AAClC,WAAS,KAAK,GAAI,UAAU,YAAY,EAAE,CAAE;;AAE7C,QAAO;EACN,GAAG,WAAW,MAAM,WAAW;EAC/B,OAAO;EACP,MAAM,QAAQ,MAAM,UAAU,IAAI,QAAQ,WAAW;EACrD;EACA,GAAI,SAAS,SAAS,IAAI,EAAE,UAAU,GAAG,EAAE;EAC3C,UAAU,MAAM,SAAS;EACzB,SAAS,MAAM;EACf,SAAS,MAAM;EACf,UAAU,MAAM;EAChB,WAAW,MAAM;EACjB;;AAGF,SAAgB,iCACf,OACA,MAC6B;AAC7B,QAAO,YAAY,MAAM,YAAY,EAAE,EAAE,KAAK,YAAY,EAAE,CAAC;;AAG9D,SAAgB,wCAAwC,OAA+B;CACtF,MAAM,SAAS,cAAc,MAAM,YAAY,EAAE,CAAC;AAClD,SAAQ,SAA4D;EACnE,MAAM,QAAQ,cAAc,KAAK,YAAY,EAAE,CAAC;EAChD,MAAM,6BAAa,IAAI,KAAuC;AAC9D,OAAK,MAAM,QAAQ,KAAK,QACvB,MAAK,MAAM,OAAO,KAAK,SAAS,EAAE,EAAE;GACnC,MAAM,aAAa,MAAM,IAAI,IAAI,IAAI,OAAO,IAAI,IAAI;AACpD,OAAI,WAAY,YAAW,IAAI,KAAK,WAAW;;AAGjD,SAAO,CAAC,GAAG,WAAW,QAAQ,CAAC;;;AAIjC,SAAgB,iCACf,OACuB;CACvB,MAAM,WAAW,MAAM,KAAK,EAAE,QAAQ,MAAM,KAAK,QAAQ,wBAAQ,IAAI,KAAa,CAAC;CACnF,MAAM,SAAoC,EAAE;AAC5C,MAAK,IAAI,MAAM,GAAG,MAAM,MAAM,KAAK,QAAQ,OAAO;EACjD,IAAI,SAAS;AACb,OAAK,MAAM,QAAQ,MAAM,KAAK,KAAM,OAAO;AAC1C,UAAO,SAAS,KAAM,IAAI,OAAO,CAAE;GACnC,MAAM,UAAU,KAAK,WAAW;AAChC,QAAK,IAAI,SAAS,GAAG,SAAS,SAAS,UAAU;IAChD,MAAM,QAAQ,KAAK,WAAW;AAC9B,QAAI,SAAS,OAAO,SAAS,YAAY,OACxC,QAAO,SAAS,UAAU,KAAK,IAAI,sBAAsB,MAAM;;AAGjE,UAAO,UAAU,KAAK,QAAQ,KAAK,WAAW,GAAG,QAAQ;AACzD,aAAU;;;AAGZ,QAAO,OAAO,KAAK,QAAQ,GAAG,OAAO,KAAK,UAAU,SAAS,qBAAqB,GAAG;;AAGtF,SAAS,cACR,OACA,SAOwB;AACxB,KAAI,OAAO,UAAU,YAAY,CAAC,SAAS,MAAM,CAAE,QAAO,KAAK,2BAA2B;CAC1F,MAAM,SAAS,SAAS,MAAM;CAC9B,MAAM,MAAM,WAAW,QAAQ,OAAO,KAAK,IAAI,UAAU,QAAQ,KAAK,EAAE,QAAQ,KAAK;CACrF,MAAM,WAAW,kBAAkB,OAAO,SAAS;CACnD,MAAM,aAAa,cAAc,SAAS;CAC1C,MAAM,UAAU,cAAc,OAAO,QAAQ;CAC7C,MAAM,UAAU,KAAK,IAAI,cAAc,OAAO,QAAQ,EAAE,KAAK,IAAI,GAAG,QAAQ,cAAc,CAAC;CAC3F,MAAM,WAAW,kBAAkB,OAAO,UAAU,QAAQ;CAC5D,MAAM,YAAY,mBAAmB,OAAO,UAAU;CACtD,MAAM,iBAAiB,OAAO,QAAQ,WAAW;CACjD,MAAM,WACL,QAAQ,iBAAiB,OAAO,aAAa,OAC1C,OACA,kBAAkB,OAAO,aAAa,QACrC,QACA;CACL,MAAM,OAA8B;EACnC,GAAG,WAAW,QAAQ,YAAY;EAClC,OAAO;EACP,MAAM;EACN,SAAS,iBACR,OACA,OAAO,SACP,MACC,SAAS,WAAW,IAAI,KAAK,IAAI,QAAQ,WAAW,IAAI,KAAK,CAC9D;EACD;AACD,KAAI,SAAS,SAAS,EAAG,MAAK,WAAW;AACzC,KAAI,aAAa,OAAW,MAAK,WAAW;AAC5C,KAAI,UAAU,EAAG,MAAK,UAAU;AAChC,KAAI,UAAU,EAAG,MAAK,UAAU;AAChC,KAAI,SAAU,MAAK,WAAW;AAC9B,KAAI,UAAW,MAAK,YAAY;AAChC,QAAO;;AAGR,SAAS,iBACR,SACA,YACA,SACA,aAC0B;CAC1B,MAAM,gBAAgB,UAAiC;EACtD,OAAO;EACP,MAAM,UAAU,GAAG,QAAQ,SAAS;EACpC;EACA;CACD,MAAM,SACL,OAAO,YAAY,WAChB,CAAC,aAAa,QAAQ,CAAC,GACvB,OAAO,eAAe,WACrB,CAAC,aAAa,WAAW,CAAC,GAC1B,eAAe,SACd,EAAE,GACF;AACN,KAAI,CAAC,MAAM,QAAQ,OAAO,CAAE,QAAO,KAAK,2BAA2B;CACnE,MAAM,UAAU,OAAO,KAAK,OAAO,UAAiC;AACnE,MAAI,CAAC,SAAS,MAAM,IAAI,MAAM,UAAU,UAAU,OAAO,MAAM,SAAS,SACvE,QAAO,KAAK,2BAA2B;EAExC,MAAM,QAAQ,MAAM,SAAS,EAAE;AAC/B,MAAI,CAAC,MAAM,QAAQ,MAAM,CAAE,QAAO,KAAK,8BAA8B;EACrE,MAAM,kBAA4B,EAAE;AACpC,OAAK,MAAM,QAAQ,OAAO;AACzB,OACC,OAAO,SAAS,YACf,CAAC,gBAAgB,IAAI,KAAK,IAAI,YAAY,KAAK,EAAE,UAAU,OAE5D,QAAO,KAAK,8BAA8B;AAE3C,mBAAgB,KAAK,KAAK;;AAE3B,SAAO;GACN,OAAO;GACP,MAAM,QAAQ,MAAM,KAAK,IAAI,UAAU,GAAG,QAAQ,QAAQ,QAAQ;GAClE,MAAM,MAAM;GACZ,GAAI,gBAAgB,SAAS,IAAI,EAAE,OAAO,iBAAiB,GAAG,EAAE;GAChE;GACA;AACF,QAAO,QAAQ,SAAS,IAAI,UAAU,CAAC,UAAU,QAAQ,CAAC;;AAG3D,SAAS,kBAAkB,OAA4C;AACtE,KAAI,UAAU,OAAW,QAAO,EAAE;AAClC,KAAI,CAAC,MAAM,QAAQ,MAAM,CAAE,QAAO,KAAK,8BAA8B;AACrE,QAAO,MAAM,KAAK,SAAmC;EACpD,MAAM,MAAM,SAAS,KAAK,GAAG,QAAQ,KAAK,KAAK,GAAG;AAClD,MAAI,CAAC,SAAS,KAAK,IAAI,KAAK,UAAU,UAAU,CAAC,OAAO,OAAO,KAAK,SAAS,SAC5E,QAAO,KAAK,8BAA8B;AAE3C,SAAO;GAAE,GAAG,WAAW,KAAK;GAAE,OAAO;GAAQ,MAAM;GAAK;GACvD;;AAGH,MAAM,iBAAiB,UACtB,OAAO,UAAU,YAAY,OAAO,UAAU,MAAM,IAAI,QAAQ,KAAK,SAAS,iBAC3E,QACA;AAEJ,SAAS,mBAAmB,OAAwD;AACnF,QAAO,UAAU,UAAU,UAAU,YAAY,UAAU,WAAW,UAAU,YAC7E,QACA;;AAGJ,SAAS,kBAAkB,OAAgB,SAAuC;AACjF,KAAI,CAAC,MAAM,QAAQ,MAAM,IAAI,MAAM,WAAW,WAAW,CAAC,MAAM,MAAM,WAAW,CAChF,QAAO;AACR,QAAO;;AAGR,MAAM,cAAc,UACnB,OAAO,UAAU,YACjB,OAAO,UAAU,MAAM,IACvB,SAAS,KACT,SAAS;AAEV,SAAS,gBAAgB,OAAe,QAAsB;AAC7D,KAAI,QAAQ,SAAS,yBAA0B,QAAO,KAAK,kBAAkB;;AAG9E,SAAS,cACR,UACA,KACA,QACA,SACA,SACU;AACV,MAAK,IAAI,IAAI,KAAK,IAAI,MAAM,SAAS,IACpC,MAAK,IAAI,IAAI,QAAQ,IAAI,SAAS,SAAS,IAAK,KAAI,SAAS,GAAI,IAAI,EAAE,CAAE,QAAO;AAEjF,QAAO;;AAGR,SAAS,OACR,UACA,KACA,QACA,SACA,SACO;AACP,MAAK,IAAI,IAAI,KAAK,IAAI,MAAM,SAAS,IACpC,MAAK,IAAI,IAAI,QAAQ,IAAI,SAAS,SAAS,IAAK,UAAS,IAAI,IAAI,EAAE;;AAIrE,SAAS,WACR,MACA,QACA,SACA,QACA,WACwB;CACxB,MAAM,EAAE,UAAU,WAAW,GAAG,SAAS;AACzC,KAAI,CAAC,UAAW,QAAO;AACvB,QAAO;EACN,GAAG;EACH,UAAU,OAAO,MAAM,QAAQ,SAAS,QAAQ,CAAC,KAAK,UAAU,SAAS,qBAAqB;EAC9F;;AAGF,SAAS,UACR,KACA,KACA,UACA,MACA,eAAe,OACU;AACzB,QAAO;EACN,GAAG,WAAW,KAAK,aAAa;EAChC,OAAO;EACP,MAAM;EACN;EACA,GAAI,eAAe,EAAE,cAAc,MAAM,GAAG,EAAE;EAC9C,GAAI,SAAS,SAAS,IAAI,EAAE,UAAU,GAAG,EAAE;EAC3C;;AAGF,MAAM,aAAa,SAAwC;CAC1D,OAAO;CACP,MAAM,UAAU,GAAG,IAAI,SAAS;CAChC,MAAM;CACN;AAED,SAAS,UAAU,KAAa,WAAW,OAA8B;AACxE,QAAO;EACN,OAAO;EACP,MAAM;EACN,SAAS,CAAC,UAAU,IAAI,CAAC;EACzB,GAAI,WAAW,EAAE,UAAU,MAAM,GAAG,EAAE;EACtC;;AAGF,SAAS,aACR,KACA,SACA,WACsC;AACtC,KAAI;AACH,SAAO,WAAW;UACV,OAAO;AACf,MAAI,iBAAiB,qBAAsB,QAAO,aAAa,MAAM,QAAQ,KAAK,QAAQ,KAAK;AAC/F,QAAM;;;AAIR,SAAS,aAAa,QAAuC,KAAc,MAAc;AACxF,QAAO;EACN,IAAI;EACJ;EACA;EACA,GAAI,WAAW,oBAAoB,EAAE,GAAG,EAAE,gBAAgB,mBAAmB,KAAK,KAAK,EAAE;EACzF;;AAGF,SAAS,mBAAmB,KAAc,MAAkD;CAC3F,MAAM,SAAS,SAAS,IAAI;CAC5B,MAAM,uBAAO,IAAI,KAAa;CAC9B,MAAM,WAAW,WAAW,QAAQ,OAAO,KAAK,IAAI,UAAU,GAAG,KAAK,iBAAiB,EAAE,KAAK;CAC9F,IAAI,YAAY;CAChB,MAAM,OAA+B,EAAE;AACvC,MAAK,MAAM,CAAC,UAAU,YAAY,MAAM,QAAQ,OAAO,KAAK,GAAG,OAAO,OAAO,EAAE,EAAE,SAAS,EAAE;EAC3F,MAAM,MAAM,SAAS,OAAO;EAC5B,MAAM,WAAW,MAAM,QAAQ,IAAI,MAAM,GAAG,IAAI,QAAQ,EAAE;AAC1D,MAAI,KAAK,IAAI,SAAS,QAAQ,EAAE,GAAG,UAAW,QAAO;EACrD,MAAM,SAAS,WACd,QAAQ,IAAI,KAAK,IAAI,UAAU,GAAG,SAAS,gBAAgB,WAAW,EACtE,KACA;EACD,MAAM,QAAQ,SAAS,KAAK,SAAS,cAAqC;AAMzE,UAAO,aAAa,SAJR,WACX,QAFY,SAAS,QAAQ,CAEhB,KAAK,IAAI,UAAU,GAAG,OAAO,iBAAiB,YAAY,EACvE,KACA,CACgC;IAChC;AACF,MAAI,MAAM,WAAW,EACpB,OAAM,KAAK,UAAU,WAAW,UAAU,GAAG,OAAO,QAAQ,EAAE,KAAK,CAAC,CAAC;AAEtE,eAAa,MAAM;AACnB,OAAK,KAAK;GAAE,OAAO;GAAY,MAAM;GAAQ;GAAO,CAAC;;AAEtD,KAAI,KAAK,SAAS,EAAG,QAAO;EAAE,OAAO;EAAS,MAAM;EAAU;EAAM;AAEpE,QAAO;EACN,OAAO;EACP,MAAM;EACN,MAAM,CACL;GACC,OAAO;GACP,MAPY,WAAW,UAAU,GAAG,SAAS,YAAY,EAAE,KAAK;GAQhE,OAAO,CAAC,UAAU,WAAW,UAAU,GAAG,SAAS,aAAa,EAAE,KAAK,CAAC,CAAC;GACzE,CACD;EACD;;AAGF,MAAM,gBAAgB,KAAc,SAAwC;CAC3E,OAAO;CACP,MAAM;CACN,SAAS,CAAC;EAAE,GAAG,UAAU,IAAI;EAAE,MAAM,YAAY,IAAI;EAAE,CAAC;CACxD;AAED,SAAS,YAAY,OAAgB,QAAQ,GAAW;AACvD,KAAI,QAAQ,GAAI,QAAO;AACvB,KAAI,OAAO,UAAU,SAAU,QAAO;AACtC,KAAI,MAAM,QAAQ,MAAM,CAAE,QAAO,MAAM,KAAK,UAAU,YAAY,OAAO,QAAQ,EAAE,CAAC,CAAC,KAAK,GAAG;CAC7F,MAAM,SAAS,SAAS,MAAM;AAC9B,KAAI,OAAO,OAAO,SAAS,SAAU,QAAO,OAAO;AACnD,KAAI,OAAO,OAAO,YAAY,SAAU,QAAO,OAAO;AAMtD,QAAO,YALQ,MAAM,QAAQ,OAAO,QAAQ,GACzC,OAAO,UACP,MAAM,QAAQ,OAAO,SAAS,GAC7B,OAAO,WACP,EAAE,EACqB,QAAQ,EAAE;;AAGtC,MAAM,iBAAiB,UACtB,IAAI,IAAI,MAAM,KAAK,SAAS,CAAC,KAAK,MAAM,KAAK,CAAC,CAAC;AAEhD,SAAS,YACR,OACA,MAC6B;CAC7B,MAAM,QAAQ,cAAc,MAAM;AAClC,MAAK,MAAM,QAAQ,KAAM,OAAM,IAAI,KAAK,MAAM,KAAK;AACnD,QAAO,CAAC,GAAG,MAAM,QAAQ,CAAC;;AAG3B,SAAS,UAAU,OAAuB;CACzC,IAAI,OAAO;AACX,MAAK,IAAI,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS;AAClD,UAAQ,MAAM,WAAW,MAAM;AAC/B,SAAO,KAAK,KAAK,MAAM,SAAW;;AAEnC,QAAO,iBAAiB,SAAS,GAAG,SAAS,GAAG;;AAGjD,SAAS,WAAW,MAAc,MAA2B;CAC5D,IAAI,YAAY;AAChB,MAAK,IAAI,SAAS,GAAG,KAAK,IAAI,UAAU,EAAE,SAAU,aAAY,GAAG,KAAK,GAAG;AAC3E,MAAK,IAAI,UAAU;AACnB,QAAO;;AAGR,MAAM,WAAW,QAAuB,YAAwC;CAC/E,WAAW,OAAO;CAClB,YAAY,WAAW,QAAQ,OAAO;CACtC;AAED,SAAS,WAAW,OAAgB,2BAAW,IAAI,KAAa,EAAiB;AAChF,KAAI,CAAC,SAAS,MAAM,CAAE,QAAO,EAAE;AAC/B,QAAO,OAAO,YACb,OAAO,QAAQ,MAAM,CAAC,QACpB,CAAC,SACD,CAAC,SAAS,IAAI,IAAI,IAClB,QAAQ,eACR,QAAQ,eACR,QAAQ,iBACR,CAAC,UAAU,KAAK,IAAI,CACrB,CACD;;AAGF,MAAM,YAAY,UACjB,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM;AACrE,MAAM,YAAY,UAAmC,SAAS,MAAM,GAAG,QAAQ,EAAE;AACjF,MAAM,WAAW,UAChB,OAAO,UAAU,YAAY,MAAM,SAAS,IAAI,QAAQ;AACzD,MAAM,UAAU,QAAuB,QAAyB,OAAO,OAAO,QAAQ,IAAI;AAC1F,MAAM,qBAAqB,UAC1B,SAAS,MAAM,IAAI,OAAO,MAAM,SAAS"}
|