@w100n/documents 0.16.4 → 0.17.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.
Files changed (44) hide show
  1. package/dist/{Compare-M57FG4R3.js → Compare-RHAUAKUJ.js} +2 -2
  2. package/dist/{SheetView-OEKOHMKW.js → SheetView-SBLAFGTL.js} +5 -5
  3. package/dist/{TextEditor-5S7FSLIZ.js → TextEditor-X2GSL4QM.js} +119 -27
  4. package/dist/TextEditor-X2GSL4QM.js.map +1 -0
  5. package/dist/{chunk-AKJGYZME.js → chunk-A6AHJCEK.js} +67 -832
  6. package/dist/chunk-A6AHJCEK.js.map +1 -0
  7. package/dist/{chunk-3D2G5NBI.js → chunk-ASTNK6WZ.js} +2 -2
  8. package/dist/{chunk-VNXZVOPN.js → chunk-B7C6NBBQ.js} +929 -1
  9. package/dist/chunk-B7C6NBBQ.js.map +1 -0
  10. package/dist/chunk-FFXAOK4A.js +39 -0
  11. package/dist/chunk-FFXAOK4A.js.map +1 -0
  12. package/dist/{chunk-EQLBYW42.js → chunk-GSIPTCQH.js} +9 -1
  13. package/dist/chunk-GSIPTCQH.js.map +1 -0
  14. package/dist/collab.cjs +170 -2
  15. package/dist/collab.cjs.map +1 -1
  16. package/dist/collab.d.cts +1 -1
  17. package/dist/collab.d.ts +1 -1
  18. package/dist/collab.js +3 -3
  19. package/dist/index.cjs +1204 -540
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.css +313 -0
  22. package/dist/index.css.map +1 -1
  23. package/dist/index.d.cts +2 -2
  24. package/dist/index.d.ts +2 -2
  25. package/dist/index.js +871 -494
  26. package/dist/index.js.map +1 -1
  27. package/dist/kinds.d.cts +1 -1
  28. package/dist/kinds.d.ts +1 -1
  29. package/dist/memory.cjs +3 -2
  30. package/dist/memory.cjs.map +1 -1
  31. package/dist/memory.d.cts +1 -1
  32. package/dist/memory.d.ts +1 -1
  33. package/dist/memory.js +3 -2
  34. package/dist/memory.js.map +1 -1
  35. package/dist/{types-BUO0OzOl.d.cts → types-CHmV8GLx.d.cts} +1 -0
  36. package/dist/{types-BUO0OzOl.d.ts → types-CHmV8GLx.d.ts} +1 -0
  37. package/package.json +1 -1
  38. package/dist/TextEditor-5S7FSLIZ.js.map +0 -1
  39. package/dist/chunk-AKJGYZME.js.map +0 -1
  40. package/dist/chunk-EQLBYW42.js.map +0 -1
  41. package/dist/chunk-VNXZVOPN.js.map +0 -1
  42. /package/dist/{Compare-M57FG4R3.js.map → Compare-RHAUAKUJ.js.map} +0 -0
  43. /package/dist/{SheetView-OEKOHMKW.js.map → SheetView-SBLAFGTL.js.map} +0 -0
  44. /package/dist/{chunk-3D2G5NBI.js.map → chunk-ASTNK6WZ.js.map} +0 -0
@@ -1,7 +1,870 @@
1
1
  'use client';
2
+ import {
3
+ mathml
4
+ } from "./chunk-ZAVXCH7V.js";
5
+
6
+ // src/editor/pager.ts
7
+ import { Extension } from "@tiptap/core";
8
+ import { Plugin, PluginKey } from "@tiptap/pm/state";
9
+ import { Decoration, DecorationSet } from "@tiptap/pm/view";
10
+ var a4 = { width: 793.73, height: 1122.53, margins: [96, 96, 96, 96] };
11
+ var letter = { width: 816, height: 1056 };
12
+ var paging = new PluginKey("w100n-pager");
13
+ var skip = (el) => el.classList.contains("w100n-text-gap") || el.classList.contains("ProseMirror-gapcursor");
14
+ function measure(view) {
15
+ const { page } = paging.getState(view.state);
16
+ const [top, , bottom] = page.margins;
17
+ const room = page.height - top - bottom;
18
+ const els = [...view.dom.children];
19
+ const gaps = [];
20
+ const line = page.width - page.margins[1] - page.margins[3];
21
+ const area = (list) => list.length ? 14 + list.reduce((h, text) => h + 15 * Math.max(1, Math.ceil(text.length * 5.6 / line)), 0) : 0;
22
+ let notes2 = [];
23
+ let count = 0;
24
+ let i = 0;
25
+ let shift = 0;
26
+ let start = 0;
27
+ let last = 0;
28
+ view.state.doc.forEach((node, offset) => {
29
+ let el = els[i++];
30
+ while (el && skip(el)) {
31
+ if (el.classList.contains("w100n-text-gap")) shift += el.offsetHeight;
32
+ el = els[i++];
33
+ }
34
+ if (!el) return;
35
+ const y = el.offsetTop - shift;
36
+ const end = y + el.offsetHeight;
37
+ const mine = [];
38
+ node.descendants((d) => {
39
+ if (d.type.name === "footnote") mine.push(`${count + mine.length + 1} ${d.attrs.text}`);
40
+ });
41
+ if (node.type.name === "pageBreak") {
42
+ gaps.push({ pos: offset + node.nodeSize, height: start + room - end + bottom + 24 + top, page: gaps.length + 1, notes: notes2 });
43
+ notes2 = [];
44
+ start = end;
45
+ } else if (end > start + room - area([...notes2, ...mine]) && y > start) {
46
+ gaps.push({ pos: offset, height: start + room - y + bottom + 24 + top, page: gaps.length + 1, notes: notes2 });
47
+ notes2 = [];
48
+ start = y;
49
+ }
50
+ notes2.push(...mine);
51
+ count += mine.length;
52
+ while (end > start + room) start += room;
53
+ last = end;
54
+ });
55
+ gaps.push({ pos: view.state.doc.content.size, height: Math.max(0, start + room - last), page: gaps.length + 1, end: true, notes: notes2 });
56
+ return gaps.map((g) => ({ ...g, height: Math.max(0, Math.round(g.height)) }));
57
+ }
58
+ var Pager = Extension.create({
59
+ name: "pager",
60
+ addProseMirrorPlugins: () => [new Plugin({
61
+ key: paging,
62
+ state: {
63
+ init: () => ({ set: DecorationSet.empty, page: a4, marks: { header: "", footer: "" }, flow: false }),
64
+ apply(tr, value) {
65
+ const next = tr.getMeta(paging);
66
+ return { set: next?.set ?? value.set.map(tr.mapping, tr.doc), page: next?.page ?? value.page, marks: next?.marks ?? value.marks, flow: next?.flow ?? value.flow };
67
+ }
68
+ },
69
+ props: { decorations: (state) => paging.getState(state).set },
70
+ view(view) {
71
+ let timer = 0;
72
+ let sig = "";
73
+ const run = () => {
74
+ if (!view.dom.isConnected) return;
75
+ const { marks, flow } = paging.getState(view.state);
76
+ if (flow) {
77
+ if (sig !== "flow") view.dispatch(view.state.tr.setMeta(paging, { set: DecorationSet.empty }).setMeta("addToHistory", false));
78
+ sig = "flow";
79
+ return;
80
+ }
81
+ const gaps = measure(view);
82
+ const next = gaps.map((g) => `${g.pos}:${g.height}:${g.notes.join("\n")}`).join() + `|${marks.header}|${marks.footer}`;
83
+ if (next === sig) return;
84
+ sig = next;
85
+ const line = (parent, cls, text) => {
86
+ if (!text) return;
87
+ const span = document.createElement("span");
88
+ span.className = cls;
89
+ span.textContent = text;
90
+ parent.append(span);
91
+ };
92
+ const first = Decoration.widget(0, () => {
93
+ const el = document.createElement("div");
94
+ el.className = "w100n-text-first";
95
+ el.contentEditable = "false";
96
+ line(el, "w100n-text-head", marks.header);
97
+ return el;
98
+ }, { key: `first:${marks.header}`, side: -1, ignoreSelection: true });
99
+ const set = DecorationSet.create(view.state.doc, [first, ...gaps.map((g) => Decoration.widget(g.pos, () => {
100
+ const el = document.createElement("div");
101
+ el.className = g.end ? "w100n-text-gap is-end" : "w100n-text-gap";
102
+ el.style.height = `${g.height}px`;
103
+ el.dataset.page = String(g.page);
104
+ el.contentEditable = "false";
105
+ line(el, "w100n-text-foot", marks.footer);
106
+ if (!g.end) line(el, "w100n-text-head", marks.header);
107
+ if (g.notes.length) {
108
+ const list = document.createElement("div");
109
+ list.className = "w100n-text-footnotes";
110
+ for (const note of g.notes) {
111
+ const p = document.createElement("p");
112
+ const n = document.createElement("sup");
113
+ n.textContent = note.slice(0, note.indexOf(" "));
114
+ p.append(n, note.slice(note.indexOf(" ")));
115
+ list.append(p);
116
+ }
117
+ el.append(list);
118
+ }
119
+ return el;
120
+ }, { key: `${g.pos}:${g.height}:${g.page}:${marks.header}:${marks.footer}:${g.notes.join("\n")}`, side: -1, ignoreSelection: true }))]);
121
+ view.dispatch(view.state.tr.setMeta(paging, { set }).setMeta("addToHistory", false));
122
+ };
123
+ const later = (ms) => {
124
+ clearTimeout(timer);
125
+ timer = window.setTimeout(run, ms);
126
+ };
127
+ const watch = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(() => later(200));
128
+ watch?.observe(view.dom);
129
+ later(0);
130
+ return {
131
+ update: (next, prev) => {
132
+ const now = paging.getState(next.state), was = paging.getState(prev);
133
+ if (now.page !== was.page || now.marks !== was.marks || now.flow !== was.flow) later(0);
134
+ else if (next.state.doc !== prev.doc) later(400);
135
+ },
136
+ destroy: () => {
137
+ clearTimeout(timer);
138
+ watch?.disconnect();
139
+ }
140
+ };
141
+ }
142
+ })]
143
+ });
144
+
145
+ // src/editor/extensions.ts
146
+ import { Extension as Extension2, Mark, Node } from "@tiptap/core";
147
+ import Collaboration from "@tiptap/extension-collaboration";
148
+ import CollaborationCaret from "@tiptap/extension-collaboration-caret";
149
+ import Highlight from "@tiptap/extension-highlight";
150
+ import Image from "@tiptap/extension-image";
151
+ import { TaskItem, TaskList } from "@tiptap/extension-list";
152
+ import { TableKit } from "@tiptap/extension-table";
153
+ import { Color, FontFamily, FontSize, TextStyle } from "@tiptap/extension-text-style";
154
+ import { Plugin as Plugin2, PluginKey as PluginKey2, TextSelection } from "@tiptap/pm/state";
155
+ import { StepMap } from "@tiptap/pm/transform";
156
+ import { Decoration as Decoration2, DecorationSet as DecorationSet2 } from "@tiptap/pm/view";
157
+ import StarterKit from "@tiptap/starter-kit";
158
+ import { ySyncPluginKey } from "@tiptap/y-tiptap";
159
+ var notes = new PluginKey2("w100n-notes");
160
+ var blocks = [
161
+ "paragraph",
162
+ "heading",
163
+ "bulletList",
164
+ "orderedList",
165
+ "listItem",
166
+ "taskList",
167
+ "taskItem",
168
+ "blockquote",
169
+ "codeBlock",
170
+ "horizontalRule",
171
+ "table",
172
+ "tableRow",
173
+ "tableHeader",
174
+ "tableCell",
175
+ "pageBreak",
176
+ "toc"
177
+ ];
178
+ var changed = (trs) => {
179
+ const ranges = [];
180
+ trs.forEach((tr, n) => tr.steps.forEach((step, i) => {
181
+ const slice = step.slice;
182
+ if (!slice || !slice.openStart && !slice.openEnd && !slice.content.firstChild?.isBlock) return;
183
+ const after = tr.mapping.slice(i + 1);
184
+ for (const later of trs.slice(n + 1)) after.appendMapping(later.mapping);
185
+ step.getMap().forEach((_a, _b, from, to) => ranges.push([after.map(from, -1), after.map(to, 1)]));
186
+ }));
187
+ return ranges;
188
+ };
189
+ var Cells = Extension2.create({
190
+ name: "cells",
191
+ addGlobalAttributes: () => [
192
+ { types: ["tableCell", "tableHeader"], attributes: { background: { default: null, parseHTML: (el) => el.dataset.fill ?? null, renderHTML: (attrs) => attrs.background ? { "data-fill": attrs.background, style: `background-color: ${attrs.background}` } : {} } } },
193
+ { types: ["table"], attributes: { borders: { default: null, parseHTML: (el) => el.dataset.borders ?? null, renderHTML: (attrs) => attrs.borders ? { "data-borders": attrs.borders } : {} } } }
194
+ ]
195
+ });
196
+ var searching = new PluginKey2("w100n-search");
197
+ var lookup = (doc, query, matchCase) => {
198
+ const hits = [];
199
+ if (!query) return hits;
200
+ const needle = matchCase ? query : query.toLowerCase();
201
+ doc.descendants((node, pos) => {
202
+ if (!node.isTextblock) return true;
203
+ let text = "";
204
+ const at = [];
205
+ node.forEach((child, offset) => {
206
+ const part = child.isText ? child.text : "\uFFFC";
207
+ for (let i = 0; i < part.length; i++) at.push(pos + 1 + offset + i);
208
+ text += part;
209
+ });
210
+ const hay = matchCase ? text : text.toLowerCase();
211
+ for (let i = hay.indexOf(needle); i >= 0; i = hay.indexOf(needle, i + needle.length)) hits.push({ from: at[i], to: at[i + needle.length - 1] + 1 });
212
+ return false;
213
+ });
214
+ return hits;
215
+ };
216
+ var Search = Extension2.create({
217
+ name: "search",
218
+ addProseMirrorPlugins: () => [new Plugin2({
219
+ key: searching,
220
+ state: {
221
+ init: () => ({ query: "", matchCase: false, hits: [], at: 0, set: DecorationSet2.empty }),
222
+ apply(tr, value) {
223
+ const meta = tr.getMeta(searching);
224
+ if (!meta && !tr.docChanged) return value;
225
+ const next = { ...value, ...meta };
226
+ const hits = lookup(tr.doc, next.query, next.matchCase);
227
+ const at = hits.length ? (next.at % hits.length + hits.length) % hits.length : 0;
228
+ return { ...next, hits, at, set: DecorationSet2.create(tr.doc, hits.map((h, i) => Decoration2.inline(h.from, h.to, { class: i === at ? "w100n-found is-current" : "w100n-found" }))) };
229
+ }
230
+ },
231
+ props: { decorations: (state) => searching.getState(state).set }
232
+ })]
233
+ });
234
+ var replace = (editor, text, all) => {
235
+ const { hits, at } = searching.getState(editor.state);
236
+ if (!hits.length) return 0;
237
+ const tr = editor.state.tr;
238
+ for (const hit of all ? [...hits].reverse() : [hits[at]]) tr.insertText(text, hit.from, hit.to);
239
+ editor.view.dispatch(tr);
240
+ return all ? hits.length : 1;
241
+ };
242
+ var cleanPaste = (html) => html.replace(/<!--\[if[\s\S]*?<!\[endif\]-->/g, "").replace(/<o:p>[\s\S]*?<\/o:p>/g, "").replace(/\sclass=("|')?Mso[^"'\s>]*\1?/g, "").replace(/<img\b[^>]*\ssrc=("|')file:[^"']*\1[^>]*>/gi, "").replace(/\sstyle=("|')([^"']*)\1/g, (_, q, css) => {
243
+ const kept = css.split(";").map((x) => x.trim()).filter((x) => x && !/^mso-|^tab-stops|^font-family:\s*["']?(Symbol|Wingdings)/i.test(x)).join("; ");
244
+ return kept ? ` style=${q}${kept}${q}` : "";
245
+ });
246
+ var Blocks = Extension2.create({
247
+ name: "blocks",
248
+ addGlobalAttributes: () => [{
249
+ types: blocks,
250
+ attributes: {
251
+ align: { default: null, parseHTML: (el) => el.style.textAlign || null, renderHTML: (attrs) => attrs.align ? { style: `text-align: ${attrs.align}` } : {} },
252
+ indent: { default: 0, parseHTML: (el) => Number(el.dataset.indent) || 0, renderHTML: (attrs) => attrs.indent ? { "data-indent": attrs.indent, style: `margin-left: ${attrs.indent * 0.5}in` } : {} },
253
+ line: { default: null, parseHTML: (el) => Number(el.dataset.line) || null, renderHTML: (attrs) => attrs.line ? { "data-line": attrs.line, style: `line-height: ${attrs.line * 1.15}` } : {} },
254
+ after: { default: null, parseHTML: (el) => el.dataset.after ? Number(el.dataset.after) : null, renderHTML: (attrs) => attrs.after === null || attrs.after === void 0 ? {} : { "data-after": attrs.after, style: `margin-bottom: ${attrs.after}pt` } },
255
+ ref: { default: null, rendered: false, keepOnSplit: false }
256
+ }
257
+ }],
258
+ addProseMirrorPlugins: () => [new Plugin2({
259
+ appendTransaction(trs, _old, state) {
260
+ const ranges = changed(trs);
261
+ if (!ranges.length) return null;
262
+ const seen2 = /* @__PURE__ */ new Map();
263
+ const drop = [];
264
+ const visit = (node, pos2) => {
265
+ const ref = node.attrs.ref;
266
+ if (!ref) return;
267
+ const first = seen2.get(ref);
268
+ if (!first) seen2.set(ref, { pos: pos2, node });
269
+ else if (!first.node.textContent && node.textContent) {
270
+ drop.push(first.pos);
271
+ seen2.set(ref, { pos: pos2, node });
272
+ } else drop.push(pos2);
273
+ };
274
+ const from = Math.max(0, Math.min(...ranges.map((r) => r[0])));
275
+ const to = Math.min(state.doc.content.size, Math.max(...ranges.map((r) => r[1])));
276
+ const $from = state.doc.resolve(from);
277
+ const $to = state.doc.resolve(to);
278
+ const start = Math.max(0, $from.index(0) - 1);
279
+ const end = Math.min(state.doc.childCount, $to.index(0) + 2);
280
+ let pos = 0;
281
+ for (let i = 0; i < start; i++) pos += state.doc.child(i).nodeSize;
282
+ for (let i = start; i < end; i++) {
283
+ const top = state.doc.child(i);
284
+ visit(top, pos);
285
+ top.descendants((node, at) => visit(node, pos + 1 + at));
286
+ pos += top.nodeSize;
287
+ }
288
+ if (!drop.length) return null;
289
+ const tr = state.tr;
290
+ for (const at of drop) tr.setNodeAttribute(at, "ref", null);
291
+ return tr;
292
+ }
293
+ })]
294
+ });
295
+ var PageBreak = Node.create({
296
+ name: "pageBreak",
297
+ group: "block",
298
+ atom: true,
299
+ selectable: true,
300
+ addOptions: () => ({ label: "" }),
301
+ parseHTML: () => [{ tag: "div[data-page-break]" }],
302
+ renderHTML() {
303
+ return ["div", { "data-page-break": "", "data-label": this.options.label, class: "w100n-text-break", contenteditable: "false" }];
304
+ }
305
+ });
306
+ var Formula = Node.create({
307
+ name: "math",
308
+ group: "inline",
309
+ inline: true,
310
+ atom: true,
311
+ selectable: true,
312
+ addAttributes: () => ({ latex: { default: "", parseHTML: (el) => el.getAttribute("data-math") ?? "" } }),
313
+ parseHTML: () => [{ tag: "span[data-math]" }],
314
+ renderHTML: ({ node }) => ["span", { "data-math": node.attrs.latex, class: "w100n-math" }],
315
+ addNodeView: () => ({ node }) => {
316
+ const dom = document.createElement("span");
317
+ dom.className = "w100n-math";
318
+ dom.dataset.math = node.attrs.latex;
319
+ dom.contentEditable = "false";
320
+ dom.innerHTML = mathml(node.attrs.latex);
321
+ return { dom };
322
+ }
323
+ });
324
+ var Footnote = Node.create({
325
+ name: "footnote",
326
+ group: "inline",
327
+ inline: true,
328
+ atom: true,
329
+ selectable: true,
330
+ addAttributes: () => ({
331
+ id: { default: null, parseHTML: (el) => el.getAttribute("data-note-id") },
332
+ text: { default: "", parseHTML: (el) => el.getAttribute("title") ?? "" }
333
+ }),
334
+ parseHTML: () => [{ tag: "sup[data-footnote]" }],
335
+ renderHTML: ({ node }) => ["sup", { "data-footnote": "", "data-note-id": node.attrs.id ?? void 0, title: node.attrs.text, class: "w100n-fn", contenteditable: "false" }]
336
+ });
337
+ var wikiName = (target) => target.split("#")[0].trim().replace(/\.md$/i, "");
338
+ var WikiLink = Node.create({
339
+ name: "wikilink",
340
+ group: "inline",
341
+ inline: true,
342
+ atom: true,
343
+ selectable: true,
344
+ addOptions: () => ({ known: () => true }),
345
+ addAttributes: () => ({
346
+ target: { default: "", parseHTML: (el) => el.getAttribute("data-wiki") ?? "" },
347
+ alias: { default: null, parseHTML: (el) => el.getAttribute("data-alias") }
348
+ }),
349
+ parseHTML: () => [{ tag: "span[data-wiki]" }],
350
+ renderHTML: ({ node }) => [
351
+ "span",
352
+ { "data-wiki": node.attrs.target, "data-alias": node.attrs.alias ?? void 0, class: "w100n-wiki", contenteditable: "false" },
353
+ node.attrs.alias || wikiName(node.attrs.target) || node.attrs.target
354
+ ],
355
+ addProseMirrorPlugins() {
356
+ const known = this.options.known;
357
+ return [new Plugin2({
358
+ props: {
359
+ decorations(state) {
360
+ const found = [];
361
+ state.doc.descendants((node, pos) => {
362
+ if (node.type.name === "wikilink" && !known(node.attrs.target)) found.push(Decoration2.node(pos, pos + node.nodeSize, { class: "is-missing" }));
363
+ });
364
+ return DecorationSet2.create(state.doc, found);
365
+ }
366
+ }
367
+ })];
368
+ }
369
+ });
370
+ var wikiAsk = new PluginKey2("wikiAsk");
371
+ var WikiAsk = Extension2.create({
372
+ name: "wikiAsk",
373
+ addProseMirrorPlugins() {
374
+ return [new Plugin2({
375
+ key: wikiAsk,
376
+ state: {
377
+ init: () => null,
378
+ apply(tr, _old, _before, state) {
379
+ const { $from, empty } = state.selection;
380
+ if (!empty || !$from.parent.isTextblock || $from.parent.type.spec.code) return null;
381
+ const before = $from.parent.textBetween(0, $from.parentOffset, void 0, "\uFFFC");
382
+ const m = /\[\[([^[\]\n|\ufffc]*)$/.exec(before);
383
+ return m ? { from: $from.pos - m[0].length, query: m[1] } : null;
384
+ }
385
+ }
386
+ })];
387
+ }
388
+ });
389
+ var signs = { bold: "**", italic: "*", strike: "~~", code: "`" };
390
+ var syntax = (text, pos, side) => Decoration2.widget(pos, () => {
391
+ const el = document.createElement("span");
392
+ el.className = "w100n-syntax";
393
+ el.textContent = text;
394
+ return el;
395
+ }, { side, key: `${text}:${pos}:${side}` });
396
+ var Reveal = Extension2.create({
397
+ name: "reveal",
398
+ addProseMirrorPlugins: () => [new Plugin2({
399
+ props: {
400
+ decorations(state) {
401
+ const { $from, empty } = state.selection;
402
+ if (!empty || !$from.parent.isTextblock) return null;
403
+ const found = [];
404
+ const start = $from.start();
405
+ if ($from.parent.type.name === "heading") found.push(syntax(`${"#".repeat($from.parent.attrs.level)} `, start, -1));
406
+ const at = $from.parentOffset;
407
+ for (const [name, sign] of Object.entries(signs)) {
408
+ let from = -1;
409
+ let offset = 0;
410
+ $from.parent.forEach((child) => {
411
+ const end = offset + child.nodeSize;
412
+ if (child.marks.some((m) => m.type.name === name)) {
413
+ if (from < 0) from = offset;
414
+ if (from <= at && at <= end && (end === $from.parent.content.size || !$from.parent.childAfter(end).node?.marks.some((m) => m.type.name === name))) {
415
+ found.push(syntax(sign, start + from, -1), syntax(sign, start + end, 1));
416
+ }
417
+ } else from = -1;
418
+ offset = end;
419
+ });
420
+ }
421
+ return DecorationSet2.create(state.doc, found);
422
+ }
423
+ }
424
+ })]
425
+ });
426
+ var EndNotes = Extension2.create({
427
+ name: "endNotes",
428
+ addProseMirrorPlugins: () => [new Plugin2({
429
+ props: {
430
+ decorations(state) {
431
+ const notes2 = [];
432
+ state.doc.descendants((n) => {
433
+ if (n.type.name === "footnote") notes2.push(n.attrs.text);
434
+ });
435
+ if (!notes2.length) return null;
436
+ return DecorationSet2.create(state.doc, [Decoration2.widget(state.doc.content.size, () => {
437
+ const list = document.createElement("div");
438
+ list.className = "w100n-text-endnotes";
439
+ list.contentEditable = "false";
440
+ notes2.forEach((text, i) => {
441
+ const p = list.appendChild(document.createElement("p"));
442
+ p.appendChild(document.createElement("sup")).textContent = String(i + 1);
443
+ p.append(text);
444
+ });
445
+ return list;
446
+ }, { key: notes2.join("\n"), side: 1, ignoreSelection: true })]);
447
+ }
448
+ }
449
+ })]
450
+ });
451
+ var headings = (doc, after) => {
452
+ const found = [];
453
+ doc.descendants((node, pos) => {
454
+ if (pos > after && node.type.name === "heading" && node.attrs.level <= 3 && node.textContent.trim()) found.push({ pos, level: node.attrs.level, text: node.textContent.trim() });
455
+ return !node.isTextblock;
456
+ });
457
+ return found;
458
+ };
459
+ function entries(doc, relative, after) {
460
+ const list = headings(doc, after).map((h) => [h.level, h.text]);
461
+ const top = relative && list.length ? Math.min(...list.map(([level]) => level)) - 1 : 0;
462
+ return list.map(([level, text]) => [level - top, text]);
463
+ }
464
+ var Toc = Node.create({
465
+ name: "toc",
466
+ group: "block",
467
+ atom: true,
468
+ selectable: true,
469
+ addOptions: () => ({ relative: false, label: "", empty: "" }),
470
+ addAttributes: () => ({ entries: { default: "[]" }, title: { default: null } }),
471
+ parseHTML: () => [{ tag: "nav[data-toc]" }],
472
+ renderHTML() {
473
+ return ["nav", { "data-toc": "", class: "w100n-text-toc" }];
474
+ },
475
+ addNodeView() {
476
+ return ({ editor, getPos }) => {
477
+ const dom = document.createElement("nav");
478
+ dom.className = "w100n-text-toc";
479
+ dom.contentEditable = "false";
480
+ const paint2 = () => {
481
+ const at = getPos() ?? 0;
482
+ const list = entries(editor.state.doc, this.options.relative, at);
483
+ const head = document.createElement("b");
484
+ head.textContent = this.options.label;
485
+ const items = list.map(([level, text], i) => {
486
+ const go = document.createElement("button");
487
+ go.type = "button";
488
+ go.textContent = text;
489
+ go.dataset.level = String(level);
490
+ go.onclick = () => {
491
+ const hit = headings(editor.state.doc, getPos() ?? 0)[i];
492
+ if (hit) editor.view.nodeDOM(hit.pos)?.scrollIntoView({ behavior: "smooth", block: "start" });
493
+ };
494
+ return go;
495
+ });
496
+ const empty = document.createElement("small");
497
+ empty.textContent = this.options.empty;
498
+ dom.replaceChildren(head, ...items.length ? items : [empty]);
499
+ };
500
+ paint2();
501
+ return {
502
+ dom,
503
+ update: (node) => {
504
+ if (node.type.name !== "toc") return false;
505
+ paint2();
506
+ return true;
507
+ },
508
+ ignoreMutation: () => true
509
+ };
510
+ };
511
+ },
512
+ addProseMirrorPlugins() {
513
+ const relative = this.options.relative;
514
+ return [new Plugin2({
515
+ appendTransaction(trs, _old, state) {
516
+ if (!trs.some((tr2) => tr2.docChanged && !tr2.getMeta(ySyncPluginKey))) return null;
517
+ const at = [];
518
+ state.doc.forEach((node, pos) => {
519
+ if (node.type.name === "toc") at.push(pos);
520
+ });
521
+ if (!at.length) return null;
522
+ const tr = state.tr;
523
+ for (const pos of at) {
524
+ const fresh = JSON.stringify(entries(state.doc, relative, pos));
525
+ if (state.doc.nodeAt(pos).attrs.entries !== fresh) tr.setNodeAttribute(pos, "entries", fresh);
526
+ }
527
+ return tr.docChanged ? tr : null;
528
+ }
529
+ })];
530
+ }
531
+ });
532
+ var revision = (name, tag) => Mark.create({
533
+ name,
534
+ inclusive: false,
535
+ excludes: "insertion deletion",
536
+ addAttributes: () => ({ id: { default: null }, author: { default: "" }, date: { default: "" } }),
537
+ parseHTML: () => [{ tag: `${tag}[data-rev]` }],
538
+ renderHTML: ({ HTMLAttributes }) => [tag, { "data-rev": HTMLAttributes.id, class: "w100n-text-rev", title: HTMLAttributes.author }, 0]
539
+ });
540
+ var seen = /* @__PURE__ */ new WeakMap();
541
+ function changes(doc) {
542
+ const hit = seen.get(doc);
543
+ if (hit) return hit;
544
+ const out = [];
545
+ doc.descendants((node, pos) => {
546
+ if (!node.isText) return;
547
+ const mark = node.marks.find((m) => m.type.name === "insertion" || m.type.name === "deletion");
548
+ if (!mark) return;
549
+ const last = out[out.length - 1];
550
+ if (last && last.id === mark.attrs.id && last.kind === mark.type.name && last.to === pos) Object.assign(last, { text: last.text + node.text, to: pos + node.nodeSize });
551
+ else out.push({ id: mark.attrs.id, kind: mark.type.name, author: mark.attrs.author, date: mark.attrs.date, text: node.text, from: pos, to: pos + node.nodeSize });
552
+ });
553
+ seen.set(doc, out);
554
+ return out;
555
+ }
556
+ function decide(editor, accept, id) {
557
+ const { state } = editor;
558
+ const tr = state.tr;
559
+ for (const c of changes(state.doc).filter((c2) => !id || c2.id === id).reverse()) {
560
+ if (c.kind === "insertion" === accept) tr.removeMark(c.from, c.to, state.schema.marks[c.kind].create({ id: c.id, author: c.author, date: c.date }));
561
+ else tr.delete(c.from, c.to);
562
+ }
563
+ if (tr.docChanged) editor.view.dispatch(tr);
564
+ }
565
+ var suggesting = new PluginKey2("w100n-suggest");
566
+ var Suggest = Extension2.create({
567
+ name: "suggest",
568
+ addProseMirrorPlugins() {
569
+ const stamp = (state, kind, from, to) => {
570
+ const me = suggesting.getState(state).me;
571
+ const own = [state.doc.resolve(from).nodeBefore, state.doc.resolve(to).nodeAfter].flatMap((n) => n?.marks ?? []).find((m) => m.type.name === kind && m.attrs.author === me);
572
+ return state.schema.marks[kind].create(own ? own.attrs : { id: Math.random().toString(36).slice(2, 10), author: me, date: (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d+Z$/, "Z") });
573
+ };
574
+ const strike = (tr, state, from, to) => {
575
+ const parts = [];
576
+ state.doc.nodesBetween(from, to, (node, pos) => {
577
+ if (!node.isText) return;
578
+ const a = Math.max(from, pos), b = Math.min(to, pos + node.nodeSize);
579
+ if (b > a && !node.marks.some((m) => m.type.name === "deletion")) parts.push({ from: a, to: b, added: node.marks.some((m) => m.type.name === "insertion") });
580
+ });
581
+ const mark = stamp(state, "deletion", from, to);
582
+ for (const p of parts.reverse()) {
583
+ if (p.added) tr.delete(p.from, p.to);
584
+ else tr.addMark(p.from, p.to, mark);
585
+ }
586
+ };
587
+ const type = (view, from, to, text) => {
588
+ const { state } = view;
589
+ const tr = state.tr;
590
+ if (to > from) strike(tr, state, from, to);
591
+ const at = tr.mapping.map(to);
592
+ const kept = (state.storedMarks ?? state.doc.resolve(from).marks()).filter((m) => m.type.name !== "insertion" && m.type.name !== "deletion");
593
+ tr.insert(at, state.schema.text(text, [...kept, stamp(state, "insertion", from, to)]));
594
+ tr.setSelection(TextSelection.create(tr.doc, at + text.length));
595
+ view.dispatch(tr.scrollIntoView());
596
+ return true;
597
+ };
598
+ return [new Plugin2({
599
+ key: suggesting,
600
+ state: {
601
+ init: () => ({ on: false, me: "" }),
602
+ apply: (tr, value) => tr.getMeta(suggesting) ?? value
603
+ },
604
+ props: {
605
+ handleTextInput(view, from, to, text) {
606
+ return suggesting.getState(view.state).on && type(view, from, to, text);
607
+ },
608
+ handlePaste(view, _event, slice) {
609
+ if (!suggesting.getState(view.state).on) return false;
610
+ const { from, to } = view.state.selection;
611
+ return type(view, from, to, slice.content.textBetween(0, slice.content.size, "\n"));
612
+ },
613
+ handleKeyDown(view, event) {
614
+ const { state } = view;
615
+ if (!suggesting.getState(state).on || event.key !== "Backspace" && event.key !== "Delete" || event.metaKey || event.ctrlKey || event.altKey) return false;
616
+ const { from, to, empty, $from } = state.selection;
617
+ const back = event.key === "Backspace";
618
+ let at = from;
619
+ if (empty) {
620
+ const skip2 = (pos) => state.doc.resolve(pos)[back ? "nodeBefore" : "nodeAfter"]?.marks.some((m) => m.type.name === "deletion");
621
+ while (skip2(at)) at += back ? -1 : 1;
622
+ if (back ? at <= $from.start() : at >= $from.end()) return false;
623
+ }
624
+ const tr = state.tr;
625
+ if (empty) strike(tr, state, back ? at - 1 : at, back ? at : at + 1);
626
+ else strike(tr, state, from, to);
627
+ const caret = empty ? tr.mapping.map(back ? at - 1 : at + 1, back ? -1 : 1) : tr.mapping.map(back ? from : to);
628
+ tr.setSelection(TextSelection.create(tr.doc, caret));
629
+ view.dispatch(tr.scrollIntoView());
630
+ return true;
631
+ }
632
+ }
633
+ })];
634
+ }
635
+ });
636
+ var Note = Mark.create({
637
+ name: "comment",
638
+ inclusive: false,
639
+ excludes: "",
640
+ addAttributes: () => ({ id: { default: null, renderHTML: (attrs) => ({ "data-comment": attrs.id }) } }),
641
+ renderHTML: ({ HTMLAttributes }) => ["span", HTMLAttributes, 0]
642
+ });
643
+ var locks = new PluginKey2("w100n-locks");
644
+ var locked = (node) => node.type.name === "paragraph" && String(node.attrs.ref ?? "").startsWith("lock:");
645
+ var scan = (doc) => {
646
+ const spans = [];
647
+ doc.descendants((node, pos) => {
648
+ if (!locked(node)) return true;
649
+ spans.push({ from: pos, to: pos + node.nodeSize });
650
+ return false;
651
+ });
652
+ return spans;
653
+ };
654
+ var Locks = Extension2.create({
655
+ name: "locks",
656
+ addOptions: () => ({ label: "" }),
657
+ addProseMirrorPlugins() {
658
+ const shade = (doc, spans) => DecorationSet2.create(doc, spans.map((s) => Decoration2.node(s.from, s.to, { class: "w100n-text-lock", contenteditable: "false", "data-label": this.options.label })));
659
+ return [new Plugin2({
660
+ key: locks,
661
+ state: {
662
+ init: (_config, state) => {
663
+ const spans = scan(state.doc);
664
+ return { spans, set: shade(state.doc, spans) };
665
+ },
666
+ apply(tr, value) {
667
+ if (!tr.docChanged) return value;
668
+ const fresh = tr.steps.some((step) => {
669
+ let found = false;
670
+ step.slice?.content.descendants((node) => {
671
+ found || (found = locked(node));
672
+ return !found;
673
+ });
674
+ return found;
675
+ });
676
+ const spans = fresh ? scan(tr.doc) : value.spans.map((s) => ({ from: tr.mapping.map(s.from, 1), to: tr.mapping.map(s.to, -1) })).filter((s) => s.to > s.from);
677
+ return { spans, set: spans.length ? shade(tr.doc, spans) : DecorationSet2.empty };
678
+ }
679
+ },
680
+ filterTransaction(tr, state) {
681
+ let spans = locks.getState(state).spans;
682
+ if (!spans.length || !tr.docChanged) return true;
683
+ return tr.mapping.maps.every((map) => {
684
+ let ok = true;
685
+ map.forEach((from, to) => {
686
+ for (const s of spans) if ((from < s.to && to > s.from || from > s.from && from < s.to) && !(from <= s.from && to >= s.to)) ok = false;
687
+ });
688
+ spans = spans.map((s) => ({ from: map.map(s.from, 1), to: map.map(s.to, -1) }));
689
+ return ok;
690
+ });
691
+ },
692
+ props: {
693
+ decorations: (state) => locks.getState(state).set,
694
+ handleKeyDown(view, event) {
695
+ const back = event.key === "Backspace";
696
+ const { $from, empty } = view.state.selection;
697
+ if (!back && event.key !== "Delete" || !empty || $from.depth < 1) return false;
698
+ if (back ? $from.parentOffset !== 0 : $from.parentOffset !== $from.parent.content.size) return false;
699
+ const at = back ? $from.before() : $from.after();
700
+ const node = back ? view.state.doc.resolve(at).nodeBefore : view.state.doc.resolve(at).nodeAfter;
701
+ if (!node || !locked(node)) return false;
702
+ view.dispatch(view.state.tr.delete(back ? at - node.nodeSize : at, back ? at : at + node.nodeSize));
703
+ return true;
704
+ }
705
+ }
706
+ })];
707
+ }
708
+ });
709
+ var paint = (doc, spots, active, pending) => DecorationSet2.create(doc, [
710
+ ...spots.filter((s) => s.to > s.from).map((s) => Decoration2.inline(s.from, s.to, { class: s.id === active ? "w100n-text-note is-active" : "w100n-text-note", "data-note": s.id })),
711
+ ...pending && pending.to > pending.from ? [Decoration2.inline(pending.from, pending.to, { class: "w100n-text-note is-active" })] : []
712
+ ]);
713
+ var remap = (tr) => {
714
+ const start = tr.before.content.findDiffStart(tr.doc.content);
715
+ if (!tr.getMeta(ySyncPluginKey) || start === null) return tr.mapping;
716
+ let { a, b } = tr.before.content.findDiffEnd(tr.doc.content);
717
+ if (a < start) [a, b] = [start, b + start - a];
718
+ if (b < start) [a, b] = [a + start - b, start];
719
+ return new StepMap([start, a - start, b - start]);
720
+ };
721
+ var Notes = Extension2.create({
722
+ name: "notes",
723
+ addProseMirrorPlugins: () => [new Plugin2({
724
+ key: notes,
725
+ state: {
726
+ init: (_config, state) => ({ spots: [], active: null, pending: null, set: DecorationSet2.create(state.doc, []) }),
727
+ apply(tr, value) {
728
+ const next = tr.getMeta(notes);
729
+ if (!next && (!tr.docChanged || !value.spots.length && !value.pending)) return value;
730
+ const by = remap(tr);
731
+ const map = (r) => ({ ...r, from: by.map(r.from, 1), to: by.map(r.to, -1) });
732
+ const merged = { ...value, spots: value.spots.map(map), pending: value.pending && map(value.pending), ...next };
733
+ return { ...merged, set: paint(tr.doc, merged.spots, merged.active, merged.pending) };
734
+ }
735
+ },
736
+ props: { decorations: (state) => notes.getState(state).set }
737
+ })]
738
+ });
739
+ var script = (name, tag, other) => Mark.create({
740
+ name,
741
+ excludes: other,
742
+ parseHTML: () => [{ tag }, { style: `vertical-align=${name === "superscript" ? "super" : "sub"}` }],
743
+ renderHTML: () => [tag, 0],
744
+ addKeyboardShortcuts() {
745
+ return { [name === "superscript" ? "Mod-." : "Mod-,"]: () => this.editor.commands.toggleMark(name) };
746
+ }
747
+ });
748
+ function kit(kind, t, live, wiki) {
749
+ return [
750
+ StarterKit.configure({ trailingNode: false, link: { openOnClick: false, autolink: true, defaultProtocol: "https" }, dropcursor: { color: "#8b5cf6", width: 2 }, ...live ? { undoRedo: false } : {} }),
751
+ TaskList,
752
+ TaskItem.configure({ nested: true, a11y: { checkboxLabel: (node) => node.textContent || t.tasks } }),
753
+ TableKit.configure({ table: { resizable: true, cellMinWidth: 32 } }),
754
+ Cells,
755
+ Search,
756
+ Image.extend({
757
+ addAttributes() {
758
+ return { ...this.parent?.(), wrap: { default: null, parseHTML: (el) => el.dataset.wrap ?? null, renderHTML: (attrs) => attrs.wrap ? { "data-wrap": attrs.wrap } : {} } };
759
+ }
760
+ }).configure({ inline: true, allowBase64: true, resize: { enabled: true, directions: ["top-left", "top-right", "bottom-left", "bottom-right"], minWidth: 24, minHeight: 24, alwaysPreserveAspectRatio: true } }),
761
+ Highlight.configure({ multicolor: true }),
762
+ TextStyle,
763
+ Color,
764
+ FontSize,
765
+ FontFamily,
766
+ script("superscript", "sup", "subscript"),
767
+ script("subscript", "sub", "superscript"),
768
+ Blocks,
769
+ PageBreak.configure({ label: t.pageBreak }),
770
+ Toc.configure({ relative: kind === "markdown", label: t.toc, empty: t.tocEmpty }),
771
+ Note,
772
+ Notes,
773
+ Formula,
774
+ Footnote,
775
+ EndNotes,
776
+ WikiLink.configure({ known: wiki?.known ?? (() => true) }),
777
+ ...kind === "markdown" && wiki ? [WikiAsk, Reveal] : [],
778
+ ...kind === "docx" ? [Pager, Locks.configure({ label: t.locked }), revision("insertion", "ins"), revision("deletion", "del"), Suggest] : [],
779
+ ...live ? [Collaboration.configure({ document: live.doc }), CollaborationCaret.configure({ provider: live.link, user: live.user })] : []
780
+ ];
781
+ }
782
+ var textblocks = (editor, change) => editor.chain().focus().command(({ tr, state }) => {
783
+ state.doc.nodesBetween(state.selection.from, state.selection.to, (node, pos) => {
784
+ if (!node.isTextblock) return true;
785
+ for (const [key, value] of Object.entries(change(node.attrs))) if (node.attrs[key] !== value) tr.setNodeAttribute(pos, key, value);
786
+ return false;
787
+ });
788
+ return true;
789
+ }).run();
790
+ var align = (editor, value) => textblocks(editor, () => ({ align: value === "left" ? null : value }));
791
+ var spacing = (editor, change) => textblocks(editor, () => change);
792
+ var indent = (editor, step) => {
793
+ const type = editor.isActive("taskItem") ? "taskItem" : editor.isActive("listItem") ? "listItem" : null;
794
+ if (type) return step > 0 ? editor.chain().focus().sinkListItem(type).run() : editor.chain().focus().liftListItem(type).run();
795
+ return textblocks(editor, (attrs) => ({ indent: Math.min(8, Math.max(0, Number(attrs.indent) + step)) }));
796
+ };
797
+ var clear = (editor) => {
798
+ const chain = editor.chain().focus();
799
+ for (const mark of ["bold", "italic", "underline", "strike", "code", "highlight", "textStyle"]) chain.unsetMark(mark);
800
+ chain.run();
801
+ return textblocks(editor, () => ({ align: null, indent: 0 }));
802
+ };
803
+ function locate(doc, list) {
804
+ if (!list.length) return [];
805
+ const marked = /* @__PURE__ */ new Map();
806
+ doc.descendants((node, pos) => {
807
+ if (!node.isText) return;
808
+ for (const mark of node.marks) {
809
+ if (mark.type.name !== "comment") continue;
810
+ const found = marked.get(mark.attrs.id);
811
+ if (found) Object.assign(found, { to: pos + node.nodeSize, text: found.text + node.text });
812
+ else marked.set(mark.attrs.id, { from: pos, to: pos + node.nodeSize, text: node.text });
813
+ }
814
+ });
815
+ const claimed = /* @__PURE__ */ new Set();
816
+ const search = (quote) => {
817
+ const line = quote.split("\n").find((part) => part.trim())?.trim();
818
+ let hit = null;
819
+ if (line) doc.descendants((node, pos) => {
820
+ if (hit) return false;
821
+ if (!node.isTextblock) return true;
822
+ const at = node.textBetween(0, node.content.size, void 0, "\uFFFC").indexOf(line);
823
+ if (at >= 0) hit = { from: pos + 1 + at, to: pos + 1 + at + line.length };
824
+ return false;
825
+ });
826
+ return hit;
827
+ };
828
+ return list.flatMap((c) => {
829
+ const own = [c.anchor, c.id].find((id) => id && marked.has(id));
830
+ let range = own ? marked.get(own) : void 0;
831
+ if (!range) {
832
+ const twin = [...marked].find(([id, m]) => !claimed.has(id) && m.text === c.quote);
833
+ if (twin) {
834
+ claimed.add(twin[0]);
835
+ range = twin[1];
836
+ }
837
+ }
838
+ range ?? (range = search(c.quote));
839
+ return range ? [{ id: c.id, from: range.from, to: range.to }] : [];
840
+ });
841
+ }
2
842
 
3
843
  // src/text.ts
4
844
  var en = {
845
+ elsewhere: "Other",
846
+ wikiCreate: "Create \u201C{name}\u201D",
847
+ wikiNew: "new note",
848
+ wikiKeys: "\u2191\u2193 pick \xB7 \u21B5 link \xB7 | alias",
849
+ tree: "Tree",
850
+ cards: "Cards",
851
+ openNote: "Open note",
852
+ findNote: "Type a note name",
853
+ createNote: "Create note \u201C{name}\u201D",
854
+ noNote: "No notes match",
855
+ keysOpen: "\u2191\u2193 move \xB7 \u21B5 open \xB7 esc close",
856
+ commands: "Commands",
857
+ newNote: "New note",
858
+ searchAll: "Search in all notes",
859
+ showOutline: "Show outline",
860
+ showLinks: "Show backlinks",
861
+ showVersions: "Show versions",
862
+ showComments: "Show comments",
863
+ keysRun: "\u2191\u2193 move \xB7 \u21B5 run \xB7 esc close",
864
+ links: "Links",
865
+ linked: "Linked mentions",
866
+ unlinked: "Unlinked mentions",
867
+ noBacklinks: "Nothing links here yet",
5
868
  documents: "Documents",
6
869
  hint: "Files of your projects: read, edit and comment in one place",
7
870
  loose: "Without a folder",
@@ -355,6 +1218,29 @@ var en = {
355
1218
  uploadFailed: "Could not upload the file"
356
1219
  };
357
1220
  var pl = {
1221
+ elsewhere: "Inne",
1222
+ wikiCreate: "Utw\xF3rz \u201E{name}\u201D",
1223
+ wikiNew: "nowa notatka",
1224
+ wikiKeys: "\u2191\u2193 wyb\xF3r \xB7 \u21B5 link \xB7 | alias",
1225
+ tree: "Drzewo",
1226
+ cards: "Karty",
1227
+ openNote: "Otw\xF3rz notatk\u0119",
1228
+ findNote: "Wpisz nazw\u0119 notatki",
1229
+ createNote: "Utw\xF3rz notatk\u0119 \u201E{name}\u201D",
1230
+ noNote: "Brak pasuj\u0105cych notatek",
1231
+ keysOpen: "\u2191\u2193 ruch \xB7 \u21B5 otw\xF3rz \xB7 esc zamknij",
1232
+ commands: "Polecenia",
1233
+ newNote: "Nowa notatka",
1234
+ searchAll: "Szukaj we wszystkich notatkach",
1235
+ showOutline: "Poka\u017C spis",
1236
+ showLinks: "Poka\u017C odno\u015Bniki",
1237
+ showVersions: "Poka\u017C wersje",
1238
+ showComments: "Poka\u017C komentarze",
1239
+ keysRun: "\u2191\u2193 ruch \xB7 \u21B5 uruchom \xB7 esc zamknij",
1240
+ links: "Odno\u015Bniki",
1241
+ linked: "Linki do tej notatki",
1242
+ unlinked: "Wzmianki bez linku",
1243
+ noBacklinks: "Nic tu jeszcze nie linkuje",
358
1244
  documents: "Dokumenty",
359
1245
  hint: "Pliki Twoich projekt\xF3w: czytaj, edytuj i komentuj w jednym miejscu",
360
1246
  loose: "Bez folderu",
@@ -708,6 +1594,29 @@ var pl = {
708
1594
  uploadFailed: "Nie uda\u0142o si\u0119 wgra\u0107 pliku"
709
1595
  };
710
1596
  var uk = {
1597
+ elsewhere: "\u0406\u043D\u0448\u0435",
1598
+ wikiCreate: "\u0421\u0442\u0432\u043E\u0440\u0438\u0442\u0438 \xAB{name}\xBB",
1599
+ wikiNew: "\u043D\u043E\u0432\u0430 \u043D\u043E\u0442\u0430\u0442\u043A\u0430",
1600
+ wikiKeys: "\u2191\u2193 \u0432\u0438\u0431\u0456\u0440 \xB7 \u21B5 \u043F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F \xB7 | \u043F\u0456\u0434\u043F\u0438\u0441",
1601
+ tree: "\u0414\u0435\u0440\u0435\u0432\u043E",
1602
+ cards: "\u041A\u0430\u0440\u0442\u043A\u0438",
1603
+ openNote: "\u0412\u0456\u0434\u043A\u0440\u0438\u0442\u0438 \u043D\u043E\u0442\u0430\u0442\u043A\u0443",
1604
+ findNote: "\u0412\u0432\u0435\u0434\u0456\u0442\u044C \u043D\u0430\u0437\u0432\u0443 \u043D\u043E\u0442\u0430\u0442\u043A\u0438",
1605
+ createNote: "\u0421\u0442\u0432\u043E\u0440\u0438\u0442\u0438 \u043D\u043E\u0442\u0430\u0442\u043A\u0443 \xAB{name}\xBB",
1606
+ noNote: "\u041D\u0435\u043C\u0430\u0454 \u0442\u0430\u043A\u0438\u0445 \u043D\u043E\u0442\u0430\u0442\u043E\u043A",
1607
+ keysOpen: "\u2191\u2193 \u0440\u0443\u0445 \xB7 \u21B5 \u0432\u0456\u0434\u043A\u0440\u0438\u0442\u0438 \xB7 esc \u0437\u0430\u043A\u0440\u0438\u0442\u0438",
1608
+ commands: "\u041A\u043E\u043C\u0430\u043D\u0434\u0438",
1609
+ newNote: "\u041D\u043E\u0432\u0430 \u043D\u043E\u0442\u0430\u0442\u043A\u0430",
1610
+ searchAll: "\u0428\u0443\u043A\u0430\u0442\u0438 \u0432 \u0443\u0441\u0456\u0445 \u043D\u043E\u0442\u0430\u0442\u043A\u0430\u0445",
1611
+ showOutline: "\u041F\u043E\u043A\u0430\u0437\u0430\u0442\u0438 \u0437\u043C\u0456\u0441\u0442",
1612
+ showLinks: "\u041F\u043E\u043A\u0430\u0437\u0430\u0442\u0438 \u043F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F",
1613
+ showVersions: "\u041F\u043E\u043A\u0430\u0437\u0430\u0442\u0438 \u0432\u0435\u0440\u0441\u0456\u0457",
1614
+ showComments: "\u041F\u043E\u043A\u0430\u0437\u0430\u0442\u0438 \u043A\u043E\u043C\u0435\u043D\u0442\u0430\u0440\u0456",
1615
+ keysRun: "\u2191\u2193 \u0440\u0443\u0445 \xB7 \u21B5 \u0432\u0438\u043A\u043E\u043D\u0430\u0442\u0438 \xB7 esc \u0437\u0430\u043A\u0440\u0438\u0442\u0438",
1616
+ links: "\u041F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F",
1617
+ linked: "\u041F\u043E\u0441\u0438\u043B\u0430\u044E\u0442\u044C\u0441\u044F \u0441\u044E\u0434\u0438",
1618
+ unlinked: "\u0417\u0433\u0430\u0434\u043A\u0438 \u0431\u0435\u0437 \u043F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F",
1619
+ noBacklinks: "\u0421\u044E\u0434\u0438 \u0449\u0435 \u043D\u0456\u0449\u043E \u043D\u0435 \u043F\u043E\u0441\u0438\u043B\u0430\u0454\u0442\u044C\u0441\u044F",
711
1620
  documents: "\u0414\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0438",
712
1621
  hint: "\u0424\u0430\u0439\u043B\u0438 \u0432\u0430\u0448\u0438\u0445 \u043F\u0440\u043E\u0454\u043A\u0442\u0456\u0432: \u0447\u0438\u0442\u0430\u0439\u0442\u0435, \u0440\u0435\u0434\u0430\u0433\u0443\u0439\u0442\u0435 \u0439 \u043A\u043E\u043C\u0435\u043D\u0442\u0443\u0439\u0442\u0435 \u0432 \u043E\u0434\u043D\u043E\u043C\u0443 \u043C\u0456\u0441\u0446\u0456",
713
1622
  loose: "\u0411\u0435\u0437 \u0442\u0435\u043A\u0438",
@@ -1063,6 +1972,25 @@ var uk = {
1063
1972
  var texts = { en, pl, uk };
1064
1973
 
1065
1974
  export {
1975
+ a4,
1976
+ letter,
1977
+ paging,
1978
+ notes,
1979
+ searching,
1980
+ replace,
1981
+ cleanPaste,
1982
+ wikiName,
1983
+ wikiAsk,
1984
+ entries,
1985
+ changes,
1986
+ decide,
1987
+ suggesting,
1988
+ kit,
1989
+ align,
1990
+ spacing,
1991
+ indent,
1992
+ clear,
1993
+ locate,
1066
1994
  texts
1067
1995
  };
1068
- //# sourceMappingURL=chunk-VNXZVOPN.js.map
1996
+ //# sourceMappingURL=chunk-B7C6NBBQ.js.map