@w100n/documents 0.1.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.
@@ -0,0 +1,37 @@
1
+ 'use client';
2
+
3
+ // src/kinds.ts
4
+ var byExtension = {
5
+ docx: "docx",
6
+ md: "markdown",
7
+ markdown: "markdown",
8
+ pdf: "pdf",
9
+ xlsx: "sheet",
10
+ csv: "sheet",
11
+ html: "slides",
12
+ htm: "slides"
13
+ };
14
+ var byMime = {
15
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document": "docx",
16
+ "text/markdown": "markdown",
17
+ "application/pdf": "pdf",
18
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "sheet",
19
+ "text/csv": "sheet",
20
+ "text/html": "slides"
21
+ };
22
+ var kinds = ["docx", "markdown", "pdf", "sheet", "slides"];
23
+ function kindOf(name, mimeType) {
24
+ const extension = name.includes(".") ? name.split(".").pop().toLowerCase() : "";
25
+ return byExtension[extension] ?? (mimeType ? byMime[mimeType.split(";")[0].trim().toLowerCase()] : void 0) ?? null;
26
+ }
27
+ function matches(doc, query, kind) {
28
+ const words = query.toLocaleLowerCase().split(/\s+/).filter(Boolean);
29
+ return (kind === "all" || doc.kind === kind) && words.every((word) => doc.name.toLocaleLowerCase().includes(word));
30
+ }
31
+
32
+ export {
33
+ kinds,
34
+ kindOf,
35
+ matches
36
+ };
37
+ //# sourceMappingURL=chunk-KEV4R7W5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/kinds.ts"],"sourcesContent":["import type { DocumentKind } from './types';\n\nconst byExtension: Record<string, DocumentKind> = {\n docx: 'docx', md: 'markdown', markdown: 'markdown', pdf: 'pdf', xlsx: 'sheet', csv: 'sheet', html: 'slides', htm: 'slides',\n};\n\nconst byMime: Record<string, DocumentKind> = {\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'docx',\n 'text/markdown': 'markdown',\n 'application/pdf': 'pdf',\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'sheet',\n 'text/csv': 'sheet',\n 'text/html': 'slides',\n};\n\nexport const kinds: DocumentKind[] = ['docx', 'markdown', 'pdf', 'sheet', 'slides'];\n\nexport function kindOf(name: string, mimeType?: string | null): DocumentKind | null {\n const extension = name.includes('.') ? name.split('.').pop()!.toLowerCase() : '';\n return byExtension[extension] ?? (mimeType ? byMime[mimeType.split(';')[0].trim().toLowerCase()] : undefined) ?? null;\n}\n\nexport function matches(doc: { name: string; kind: DocumentKind }, query: string, kind: DocumentKind | 'all') {\n const words = query.toLocaleLowerCase().split(/\\s+/).filter(Boolean);\n return (kind === 'all' || doc.kind === kind) && words.every(word => doc.name.toLocaleLowerCase().includes(word));\n}\n"],"mappings":";;;AAEA,IAAM,cAA4C;AAAA,EAChD,MAAM;AAAA,EAAQ,IAAI;AAAA,EAAY,UAAU;AAAA,EAAY,KAAK;AAAA,EAAO,MAAM;AAAA,EAAS,KAAK;AAAA,EAAS,MAAM;AAAA,EAAU,KAAK;AACpH;AAEA,IAAM,SAAuC;AAAA,EAC3C,2EAA2E;AAAA,EAC3E,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EACnB,qEAAqE;AAAA,EACrE,YAAY;AAAA,EACZ,aAAa;AACf;AAEO,IAAM,QAAwB,CAAC,QAAQ,YAAY,OAAO,SAAS,QAAQ;AAE3E,SAAS,OAAO,MAAc,UAA+C;AAClF,QAAM,YAAY,KAAK,SAAS,GAAG,IAAI,KAAK,MAAM,GAAG,EAAE,IAAI,EAAG,YAAY,IAAI;AAC9E,SAAO,YAAY,SAAS,MAAM,WAAW,OAAO,SAAS,MAAM,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,YAAY,CAAC,IAAI,WAAc;AACnH;AAEO,SAAS,QAAQ,KAA2C,OAAe,MAA4B;AAC5G,QAAM,QAAQ,MAAM,kBAAkB,EAAE,MAAM,KAAK,EAAE,OAAO,OAAO;AACnE,UAAQ,SAAS,SAAS,IAAI,SAAS,SAAS,MAAM,MAAM,UAAQ,IAAI,KAAK,kBAAkB,EAAE,SAAS,IAAI,CAAC;AACjH;","names":[]}
package/dist/index.cjs ADDED
@@ -0,0 +1,475 @@
1
+ 'use client';
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+
31
+ // src/index.ts
32
+ var index_exports = {};
33
+ __export(index_exports, {
34
+ DocumentsWorkspace: () => DocumentsWorkspace,
35
+ kindOf: () => kindOf,
36
+ kinds: () => kinds,
37
+ matches: () => matches
38
+ });
39
+ module.exports = __toCommonJS(index_exports);
40
+
41
+ // src/DocumentsWorkspace.tsx
42
+ var import_react5 = require("react");
43
+ var import_lucide_react = require("lucide-react");
44
+
45
+ // src/kinds.ts
46
+ var byExtension = {
47
+ docx: "docx",
48
+ md: "markdown",
49
+ markdown: "markdown",
50
+ pdf: "pdf",
51
+ xlsx: "sheet",
52
+ csv: "sheet",
53
+ html: "slides",
54
+ htm: "slides"
55
+ };
56
+ var byMime = {
57
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document": "docx",
58
+ "text/markdown": "markdown",
59
+ "application/pdf": "pdf",
60
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "sheet",
61
+ "text/csv": "sheet",
62
+ "text/html": "slides"
63
+ };
64
+ var kinds = ["docx", "markdown", "pdf", "sheet", "slides"];
65
+ function kindOf(name, mimeType) {
66
+ const extension = name.includes(".") ? name.split(".").pop().toLowerCase() : "";
67
+ return byExtension[extension] ?? (mimeType ? byMime[mimeType.split(";")[0].trim().toLowerCase()] : void 0) ?? null;
68
+ }
69
+ function matches(doc, query, kind) {
70
+ const words = query.toLocaleLowerCase().split(/\s+/).filter(Boolean);
71
+ return (kind === "all" || doc.kind === kind) && words.every((word) => doc.name.toLocaleLowerCase().includes(word));
72
+ }
73
+
74
+ // src/text.ts
75
+ var en = {
76
+ documents: "Documents",
77
+ search: "Search documents",
78
+ all: "All",
79
+ empty: "No documents here yet",
80
+ nothing: "Nothing matches the search",
81
+ space: "Project",
82
+ pick: "Choose a document on the left",
83
+ closeList: "Hide the list",
84
+ openList: "Show the list",
85
+ outline: "Outline",
86
+ versions: "Versions",
87
+ details: "Details",
88
+ noOutline: "This document has no headings",
89
+ current: "Current",
90
+ size: "Size",
91
+ updated: "Updated",
92
+ by: "By",
93
+ kind: "Format",
94
+ rights: "You can",
95
+ view: "View",
96
+ comment: "Comment",
97
+ edit: "Edit",
98
+ failed: "Could not load",
99
+ retry: "Try again",
100
+ loading: "Loading",
101
+ sheet: "Sheet",
102
+ unsupported: "This file cannot be shown yet",
103
+ kinds: { docx: "DOCX", markdown: "Markdown", pdf: "PDF", sheet: "Sheets", slides: "Slides" }
104
+ };
105
+ var pl = {
106
+ documents: "Dokumenty",
107
+ search: "Szukaj dokument\xF3w",
108
+ all: "Wszystkie",
109
+ empty: "Nie ma tu jeszcze dokument\xF3w",
110
+ nothing: "Nic nie pasuje do wyszukiwania",
111
+ space: "Projekt",
112
+ pick: "Wybierz dokument po lewej",
113
+ closeList: "Ukryj list\u0119",
114
+ openList: "Poka\u017C list\u0119",
115
+ outline: "Spis tre\u015Bci",
116
+ versions: "Wersje",
117
+ details: "Szczeg\xF3\u0142y",
118
+ noOutline: "Ten dokument nie ma nag\u0142\xF3wk\xF3w",
119
+ current: "Bie\u017C\u0105ca",
120
+ size: "Rozmiar",
121
+ updated: "Zmieniono",
122
+ by: "Autor",
123
+ kind: "Format",
124
+ rights: "Mo\u017Cesz",
125
+ view: "Ogl\u0105da\u0107",
126
+ comment: "Komentowa\u0107",
127
+ edit: "Edytowa\u0107",
128
+ failed: "Nie uda\u0142o si\u0119 wczyta\u0107",
129
+ retry: "Spr\xF3buj ponownie",
130
+ loading: "Wczytywanie",
131
+ sheet: "Arkusz",
132
+ unsupported: "Tego pliku nie da si\u0119 jeszcze pokaza\u0107",
133
+ kinds: { docx: "DOCX", markdown: "Markdown", pdf: "PDF", sheet: "Arkusze", slides: "Slajdy" }
134
+ };
135
+ var uk = {
136
+ documents: "\u0414\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0438",
137
+ search: "\u041F\u043E\u0448\u0443\u043A \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0456\u0432",
138
+ all: "\u0423\u0441\u0456",
139
+ empty: "\u0422\u0443\u0442 \u0449\u0435 \u043D\u0435\u043C\u0430\u0454 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0456\u0432",
140
+ nothing: "\u041D\u0456\u0447\u043E\u0433\u043E \u043D\u0435 \u0437\u043D\u0430\u0439\u0434\u0435\u043D\u043E",
141
+ space: "\u041F\u0440\u043E\u0454\u043A\u0442",
142
+ pick: "\u0412\u0438\u0431\u0435\u0440\u0456\u0442\u044C \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442 \u043B\u0456\u0432\u043E\u0440\u0443\u0447",
143
+ closeList: "\u0421\u0445\u043E\u0432\u0430\u0442\u0438 \u0441\u043F\u0438\u0441\u043E\u043A",
144
+ openList: "\u041F\u043E\u043A\u0430\u0437\u0430\u0442\u0438 \u0441\u043F\u0438\u0441\u043E\u043A",
145
+ outline: "\u0417\u043C\u0456\u0441\u0442",
146
+ versions: "\u0412\u0435\u0440\u0441\u0456\u0457",
147
+ details: "\u0414\u0435\u0442\u0430\u043B\u0456",
148
+ noOutline: "\u0423 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0456 \u043D\u0435\u043C\u0430\u0454 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0456\u0432",
149
+ current: "\u041F\u043E\u0442\u043E\u0447\u043D\u0430",
150
+ size: "\u0420\u043E\u0437\u043C\u0456\u0440",
151
+ updated: "\u0417\u043C\u0456\u043D\u0435\u043D\u043E",
152
+ by: "\u0410\u0432\u0442\u043E\u0440",
153
+ kind: "\u0424\u043E\u0440\u043C\u0430\u0442",
154
+ rights: "\u0412\u0438 \u043C\u043E\u0436\u0435\u0442\u0435",
155
+ view: "\u0414\u0438\u0432\u0438\u0442\u0438\u0441\u044F",
156
+ comment: "\u041A\u043E\u043C\u0435\u043D\u0442\u0443\u0432\u0430\u0442\u0438",
157
+ edit: "\u041F\u0440\u0430\u0432\u0438\u0442\u0438",
158
+ failed: "\u041D\u0435 \u0432\u0434\u0430\u043B\u043E\u0441\u044F \u0437\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0438\u0442\u0438",
159
+ retry: "\u0421\u043F\u0440\u043E\u0431\u0443\u0432\u0430\u0442\u0438 \u0449\u0435",
160
+ loading: "\u0417\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0435\u043D\u043D\u044F",
161
+ sheet: "\u0410\u0440\u043A\u0443\u0448",
162
+ unsupported: "\u0426\u0435\u0439 \u0444\u0430\u0439\u043B \u043F\u043E\u043A\u0438 \u043D\u0435 \u043F\u043E\u043A\u0430\u0437\u0443\u0454\u0442\u044C\u0441\u044F",
163
+ kinds: { docx: "DOCX", markdown: "Markdown", pdf: "PDF", sheet: "\u0422\u0430\u0431\u043B\u0438\u0446\u0456", slides: "\u0421\u043B\u0430\u0439\u0434\u0438" }
164
+ };
165
+ var texts = { en, pl, uk };
166
+
167
+ // src/useLoad.ts
168
+ var import_react = require("react");
169
+ function useLoad(load, key) {
170
+ const [state, setState] = (0, import_react.useState)({ data: null, error: null, loading: true });
171
+ const [attempt, setAttempt] = (0, import_react.useState)(0);
172
+ (0, import_react.useEffect)(() => {
173
+ const controller = new AbortController();
174
+ setState((current) => ({ ...current, loading: true, error: null }));
175
+ load(controller.signal).then(
176
+ (data) => {
177
+ if (!controller.signal.aborted) setState({ data, error: null, loading: false });
178
+ },
179
+ (error) => {
180
+ if (!controller.signal.aborted) setState({ data: null, error: error instanceof Error ? error : new Error(String(error)), loading: false });
181
+ }
182
+ );
183
+ return () => controller.abort();
184
+ }, [...key, attempt]);
185
+ return { ...state, retry: () => setAttempt((n) => n + 1) };
186
+ }
187
+
188
+ // src/viewers/DocxView.tsx
189
+ var import_react2 = require("react");
190
+
191
+ // src/viewers/headings.ts
192
+ var last = 0;
193
+ function collect(root, selector, level = (el) => Number(el.tagName.slice(1))) {
194
+ return [...root.querySelectorAll(selector)].flatMap((el) => {
195
+ const text = el.textContent?.trim() ?? "";
196
+ if (!text) return [];
197
+ if (!el.id) el.id = `w100n-docs-h${++last}`;
198
+ return [{ id: el.id, level: Math.min(3, Math.max(1, level(el) || 1)), text }];
199
+ });
200
+ }
201
+
202
+ // src/viewers/DocxView.tsx
203
+ var import_jsx_runtime = require("react/jsx-runtime");
204
+ function DocxView({ bytes, onOutline, failed }) {
205
+ const box = (0, import_react2.useRef)(null);
206
+ const [error, setError] = (0, import_react2.useState)(false);
207
+ (0, import_react2.useLayoutEffect)(() => {
208
+ let live = true;
209
+ let width = 0;
210
+ const root = box.current;
211
+ const fit = () => {
212
+ const wrapper = root.querySelector(".w100n-docx-wrapper");
213
+ if (wrapper && width) wrapper.style.zoom = String(Math.min(1, root.clientWidth / width));
214
+ };
215
+ const watch = new ResizeObserver(fit);
216
+ root.replaceChildren();
217
+ setError(false);
218
+ import("docx-preview").then(({ renderAsync }) => renderAsync(bytes, root, void 0, { inWrapper: true, className: "w100n-docx", ignoreLastRenderedPageBreak: true })).then(() => {
219
+ if (!live) return;
220
+ width = Math.max(0, ...[...root.querySelectorAll("section.w100n-docx")].map((page) => page.offsetWidth));
221
+ fit();
222
+ watch.observe(root);
223
+ onOutline(collect(root, '[class*="heading"]', (el) => Number(/heading(\d)/i.exec(el.className)?.[1] ?? 1)));
224
+ }).catch(() => {
225
+ if (live) setError(true);
226
+ });
227
+ return () => {
228
+ live = false;
229
+ watch.disconnect();
230
+ };
231
+ }, [bytes, onOutline]);
232
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
233
+ error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "w100n-docs-note", children: failed }),
234
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ref: box, className: "w100n-docs-docx" })
235
+ ] });
236
+ }
237
+
238
+ // src/viewers/MarkdownView.tsx
239
+ var import_dompurify = __toESM(require("dompurify"), 1);
240
+ var import_marked = require("marked");
241
+ var import_react3 = require("react");
242
+ var import_jsx_runtime2 = require("react/jsx-runtime");
243
+ function MarkdownView({ bytes, onOutline }) {
244
+ const box = (0, import_react3.useRef)(null);
245
+ (0, import_react3.useLayoutEffect)(() => {
246
+ const root = box.current;
247
+ root.innerHTML = import_dompurify.default.sanitize(import_marked.marked.parse(new TextDecoder().decode(bytes), { async: false }));
248
+ onOutline(collect(root, "h1, h2, h3"));
249
+ }, [bytes, onOutline]);
250
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("article", { ref: box, className: "w100n-docs-page w100n-docs-prose" });
251
+ }
252
+
253
+ // src/viewers/PdfView.tsx
254
+ var import_react4 = require("react");
255
+ var import_jsx_runtime3 = require("react/jsx-runtime");
256
+ var last2 = 0;
257
+ function PdfView({ bytes, worker, onOutline, failed }) {
258
+ const box = (0, import_react4.useRef)(null);
259
+ const [error, setError] = (0, import_react4.useState)(false);
260
+ (0, import_react4.useEffect)(() => {
261
+ const root = box.current;
262
+ const prefix = `w100n-docs-p${++last2}`;
263
+ let stop = false;
264
+ let close = () => {
265
+ };
266
+ root.replaceChildren();
267
+ setError(false);
268
+ (async () => {
269
+ var _a;
270
+ const pdfjs = await import("pdfjs-dist");
271
+ if (worker) (_a = pdfjs.GlobalWorkerOptions).workerPort ?? (_a.workerPort = worker());
272
+ const task = pdfjs.getDocument({ data: new Uint8Array(bytes.slice(0)) });
273
+ close = () => {
274
+ void task.destroy();
275
+ };
276
+ const pdf = await task.promise;
277
+ const width = Math.max(320, root.clientWidth - 48);
278
+ for (let n = 1; n <= pdf.numPages && !stop; n++) {
279
+ const page = await pdf.getPage(n);
280
+ const scale = Math.min(2, width / page.getViewport({ scale: 1 }).width);
281
+ const viewport = page.getViewport({ scale: scale * window.devicePixelRatio });
282
+ const canvas = document.createElement("canvas");
283
+ canvas.id = `${prefix}-${n}`;
284
+ canvas.className = "w100n-docs-sheet";
285
+ canvas.width = viewport.width;
286
+ canvas.height = viewport.height;
287
+ canvas.style.width = `${viewport.width / window.devicePixelRatio}px`;
288
+ root.append(canvas);
289
+ await page.render({ canvas, canvasContext: canvas.getContext("2d"), viewport }).promise;
290
+ }
291
+ const flat = async (items, level) => (await Promise.all(items.map(async (item) => {
292
+ const dest = typeof item.dest === "string" ? await pdf.getDestination(item.dest) : item.dest;
293
+ const ref = Array.isArray(dest) ? dest[0] : null;
294
+ const index = ref && typeof ref === "object" ? await pdf.getPageIndex(ref) : null;
295
+ const here = index === null ? [] : [{ id: `${prefix}-${index + 1}`, level, text: item.title }];
296
+ return [...here, ...level < 3 ? await flat(item.items ?? [], level + 1) : []];
297
+ }))).flat();
298
+ if (!stop) onOutline(await flat(await pdf.getOutline() ?? [], 1));
299
+ })().catch(() => {
300
+ if (!stop) setError(true);
301
+ });
302
+ return () => {
303
+ stop = true;
304
+ close();
305
+ };
306
+ }, [bytes, worker, onOutline]);
307
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
308
+ error && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "w100n-docs-note", children: failed }),
309
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { ref: box, className: "w100n-docs-pdf" })
310
+ ] });
311
+ }
312
+
313
+ // src/viewers/SlidesView.tsx
314
+ var import_jsx_runtime4 = require("react/jsx-runtime");
315
+ function SlidesView({ bytes, title }) {
316
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("iframe", { className: "w100n-docs-slides", sandbox: "allow-scripts", title, srcDoc: new TextDecoder().decode(bytes) });
317
+ }
318
+
319
+ // src/DocumentsWorkspace.tsx
320
+ var import_jsx_runtime5 = require("react/jsx-runtime");
321
+ var icons = { docx: import_lucide_react.FileText, markdown: import_lucide_react.FileType, pdf: import_lucide_react.Files, sheet: import_lucide_react.FileSpreadsheet, slides: import_lucide_react.Presentation };
322
+ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onPlace, start, end }) {
323
+ const t = texts[language];
324
+ const [own, setOwn] = (0, import_react5.useState)({ spaceId: null, documentId: null });
325
+ const here = place ?? own;
326
+ const go = (next) => {
327
+ setOwn(next);
328
+ onPlace?.(next);
329
+ };
330
+ const [query, setQuery] = (0, import_react5.useState)("");
331
+ const [kind, setKind] = (0, import_react5.useState)("all");
332
+ const [listOpen, setListOpen] = (0, import_react5.useState)(true);
333
+ const [picking, setPicking] = (0, import_react5.useState)(false);
334
+ const [tab, setTab] = (0, import_react5.useState)("outline");
335
+ const [outline, setOutline] = (0, import_react5.useState)([]);
336
+ const [version, setVersion] = (0, import_react5.useState)({ documentId: null, id: null });
337
+ const versionId = version.documentId === here.documentId ? version.id : null;
338
+ const spaces = useLoad((signal) => host.spaces({ signal }), [host]);
339
+ const spaceId = here.spaceId ?? spaces.data?.[0]?.id ?? null;
340
+ const space = spaces.data?.find((item) => item.id === spaceId);
341
+ const list = useLoad((signal) => spaceId ? host.documents(spaceId, { signal }) : Promise.resolve([]), [host, spaceId]);
342
+ const doc = useLoad((signal) => here.documentId ? host.document(here.documentId, { signal }) : Promise.resolve(null), [host, here.documentId]);
343
+ const versions = useLoad((signal) => here.documentId ? host.versions(here.documentId, { signal }) : Promise.resolve([]), [host, here.documentId]);
344
+ const content = useLoad((signal) => here.documentId ? host.content(here.documentId, versionId, { signal }) : Promise.resolve(null), [host, here.documentId, versionId]);
345
+ const shown = (list.data ?? []).filter((item) => matches(item, query, kind));
346
+ const date = (iso) => new Intl.DateTimeFormat(language, { day: "numeric", month: "short", year: "numeric", hour: "2-digit", minute: "2-digit" }).format(new Date(iso));
347
+ const size = (bytes) => bytes < 1024 ? `${bytes} B` : bytes < 1048576 ? `${(bytes / 1024).toFixed(0)} KB` : `${(bytes / 1048576).toFixed(1)} MB`;
348
+ const failed = (retry) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "w100n-docs-note", children: [
349
+ t.failed,
350
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", onClick: retry, children: t.retry })
351
+ ] });
352
+ const open = (documentId) => {
353
+ setOutline([]);
354
+ setTab("outline");
355
+ go({ spaceId, documentId });
356
+ };
357
+ let stage = /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "w100n-docs-empty", children: [
358
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react.FileText, { "aria-hidden": true }),
359
+ t.pick
360
+ ] });
361
+ if (here.documentId) {
362
+ if (doc.error || content.error) stage = failed(() => {
363
+ doc.retry();
364
+ content.retry();
365
+ });
366
+ else if (!doc.data || !content.data) stage = /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "w100n-docs-empty", children: t.loading });
367
+ else if (doc.data.kind === "markdown") stage = /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MarkdownView, { bytes: content.data, onOutline: setOutline });
368
+ else if (doc.data.kind === "docx") stage = /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DocxView, { bytes: content.data, onOutline: setOutline, failed: t.failed });
369
+ else if (doc.data.kind === "pdf") stage = /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PdfView, { bytes: content.data, worker: host.pdfWorker, onOutline: setOutline, failed: t.failed });
370
+ else if (doc.data.kind === "slides") stage = /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SlidesView, { bytes: content.data, title: doc.data.name });
371
+ else stage = /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "w100n-docs-empty", children: t.unsupported });
372
+ }
373
+ const panelTabs = [["outline", import_lucide_react.ListTree, t.outline], ["versions", import_lucide_react.History, t.versions], ["details", import_lucide_react.Info, t.details]];
374
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "w100n-docs", "data-theme": theme, children: [
375
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("header", { className: "w100n-docs-bar w100n-docs-island", children: [
376
+ start,
377
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "w100n-docs-icon", onClick: () => setListOpen(!listOpen), "aria-label": listOpen ? t.closeList : t.openList, title: listOpen ? t.closeList : t.openList, children: listOpen ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react.PanelLeftClose, {}) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react.PanelLeftOpen, {}) }),
378
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("strong", { className: "w100n-docs-title", children: doc.data?.name ?? t.documents }),
379
+ doc.data && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "w100n-docs-badge", "data-kind": doc.data.kind, children: t.kinds[doc.data.kind] }),
380
+ versionId && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "w100n-docs-badge", children: versions.data?.find((v) => v.id === versionId) && date(versions.data.find((v) => v.id === versionId).createdAt) }),
381
+ end && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "w100n-docs-end", children: end })
382
+ ] }),
383
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "w100n-docs-body", children: [
384
+ listOpen && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("aside", { className: "w100n-docs-list w100n-docs-island", "aria-label": t.documents, children: [
385
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "w100n-docs-picker", children: [
386
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { type: "button", className: "w100n-docs-field", "aria-haspopup": "listbox", "aria-expanded": picking, onClick: () => setPicking(!picking), children: [
387
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "w100n-docs-dot", style: { background: space?.color ?? void 0 } }),
388
+ space?.name ?? t.space,
389
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react.ChevronDown, { "aria-hidden": true })
390
+ ] }),
391
+ picking && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("ul", { role: "listbox", className: "w100n-docs-menu", children: (spaces.data ?? []).map((item) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { type: "button", role: "option", "aria-selected": item.id === spaceId, onClick: () => {
392
+ setPicking(false);
393
+ go({ spaceId: item.id, documentId: null });
394
+ }, children: [
395
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "w100n-docs-dot", style: { background: item.color ?? void 0 } }),
396
+ item.name
397
+ ] }) }, item.id)) })
398
+ ] }),
399
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "w100n-docs-field w100n-docs-search", children: [
400
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react.Search, { "aria-hidden": true }),
401
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("input", { value: query, onChange: (event) => setQuery(event.target.value), placeholder: t.search, "aria-label": t.search })
402
+ ] }),
403
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "w100n-docs-chips", role: "group", children: ["all", ...kinds].map((item) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", "aria-pressed": kind === item, onClick: () => setKind(item), children: item === "all" ? t.all : t.kinds[item] }, item)) }),
404
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "w100n-docs-cards", children: [
405
+ list.error && failed(list.retry),
406
+ list.loading && !list.data && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "w100n-docs-muted", children: t.loading }),
407
+ list.data && !shown.length && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "w100n-docs-muted", children: list.data.length ? t.nothing : t.empty }),
408
+ shown.map((item) => {
409
+ const Icon = icons[item.kind];
410
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { type: "button", className: "w100n-docs-card", "aria-current": item.id === here.documentId, onClick: () => open(item.id), children: [
411
+ item.thumbnailUrl ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("img", { src: item.thumbnailUrl, alt: "", className: "w100n-docs-thumb" }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "w100n-docs-thumb", "data-kind": item.kind, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { "aria-hidden": true }) }),
412
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "w100n-docs-card-text", children: [
413
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("b", { children: item.name }),
414
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("small", { children: [
415
+ t.kinds[item.kind],
416
+ " \xB7 ",
417
+ date(item.updatedAt)
418
+ ] })
419
+ ] })
420
+ ] }, item.id);
421
+ })
422
+ ] })
423
+ ] }),
424
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("main", { className: "w100n-docs-stage", children: stage }),
425
+ doc.data && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("aside", { className: "w100n-docs-panel w100n-docs-island", children: [
426
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "w100n-docs-tabs", role: "tablist", children: panelTabs.map(([key, Icon, label]) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { type: "button", role: "tab", "aria-selected": tab === key, onClick: () => setTab(key), children: [
427
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { "aria-hidden": true }),
428
+ label
429
+ ] }, key)) }),
430
+ tab === "outline" && (outline.length ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("nav", { className: "w100n-docs-outline", children: outline.map((item) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", "data-level": item.level, onClick: () => document.getElementById(item.id)?.scrollIntoView({ behavior: "smooth", block: "start" }), children: item.text }, item.id)) }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "w100n-docs-muted", children: t.noOutline })),
431
+ tab === "versions" && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "w100n-docs-versions", children: [
432
+ versions.error && failed(versions.retry),
433
+ (versions.data ?? []).map((item) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
434
+ "button",
435
+ {
436
+ type: "button",
437
+ "aria-pressed": (versionId ?? "current") === item.id || !versionId && item.current,
438
+ onClick: () => setVersion({ documentId: here.documentId, id: item.current ? null : item.id }),
439
+ children: [
440
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("b", { children: [
441
+ date(item.createdAt),
442
+ item.current && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "w100n-docs-badge", children: t.current })
443
+ ] }),
444
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("small", { children: [item.author?.name, size(item.size), item.note].filter(Boolean).join(" \xB7 ") })
445
+ ]
446
+ },
447
+ item.id
448
+ ))
449
+ ] }),
450
+ tab === "details" && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("dl", { className: "w100n-docs-details", children: [
451
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("dt", { children: t.kind }),
452
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("dd", { children: t.kinds[doc.data.kind] }),
453
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("dt", { children: t.size }),
454
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("dd", { children: size(doc.data.size) }),
455
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("dt", { children: t.updated }),
456
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("dd", { children: date(doc.data.updatedAt) }),
457
+ doc.data.updatedBy && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
458
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("dt", { children: t.by }),
459
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("dd", { children: doc.data.updatedBy.name })
460
+ ] }),
461
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("dt", { children: t.rights }),
462
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("dd", { children: [doc.data.rights.view && t.view, doc.data.rights.comment && t.comment, doc.data.rights.edit && t.edit].filter(Boolean).join(", ") })
463
+ ] })
464
+ ] })
465
+ ] })
466
+ ] });
467
+ }
468
+ // Annotate the CommonJS export names for ESM import in node:
469
+ 0 && (module.exports = {
470
+ DocumentsWorkspace,
471
+ kindOf,
472
+ kinds,
473
+ matches
474
+ });
475
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/DocumentsWorkspace.tsx","../src/kinds.ts","../src/text.ts","../src/useLoad.ts","../src/viewers/DocxView.tsx","../src/viewers/headings.ts","../src/viewers/MarkdownView.tsx","../src/viewers/PdfView.tsx","../src/viewers/SlidesView.tsx"],"sourcesContent":["export { DocumentsWorkspace } from './DocumentsWorkspace';\nexport { kindOf, kinds, matches } from './kinds';\nexport type { DocumentFile, DocumentKind, DocumentsHost, DocumentSummary, DocumentVersion, Fetch, Language, Person, Place, Rights, Space } from './types';\n","import { useState, type ReactNode } from 'react';\nimport { ChevronDown, FileSpreadsheet, FileText, FileType, Files, History, Info, ListTree, PanelLeftClose, PanelLeftOpen, Presentation, Search, type LucideIcon } from 'lucide-react';\nimport { kinds, matches } from './kinds';\nimport { texts } from './text';\nimport type { DocumentKind, DocumentsHost, Language, Place } from './types';\nimport { useLoad } from './useLoad';\nimport DocxView from './viewers/DocxView';\nimport type { Heading } from './viewers/headings';\nimport MarkdownView from './viewers/MarkdownView';\nimport PdfView from './viewers/PdfView';\nimport SlidesView from './viewers/SlidesView';\nimport './styles.css';\n\nconst icons: Record<DocumentKind, LucideIcon> = { docx: FileText, markdown: FileType, pdf: Files, sheet: FileSpreadsheet, slides: Presentation };\n\ntype Tab = 'outline' | 'versions' | 'details';\n\nexport function DocumentsWorkspace({ host, language = 'en', theme = 'light', place, onPlace, start, end }: {\n host: DocumentsHost; language?: Language; theme?: 'light' | 'dark'; place?: Place; onPlace?: (place: Place) => void; start?: ReactNode; end?: ReactNode;\n}) {\n const t = texts[language];\n const [own, setOwn] = useState<Place>({ spaceId: null, documentId: null });\n const here = place ?? own;\n const go = (next: Place) => { setOwn(next); onPlace?.(next); };\n const [query, setQuery] = useState('');\n const [kind, setKind] = useState<DocumentKind | 'all'>('all');\n const [listOpen, setListOpen] = useState(true);\n const [picking, setPicking] = useState(false);\n const [tab, setTab] = useState<Tab>('outline');\n const [outline, setOutline] = useState<Heading[]>([]);\n const [version, setVersion] = useState<{ documentId: string | null; id: string | null }>({ documentId: null, id: null });\n const versionId = version.documentId === here.documentId ? version.id : null;\n\n const spaces = useLoad(signal => host.spaces({ signal }), [host]);\n const spaceId = here.spaceId ?? spaces.data?.[0]?.id ?? null;\n const space = spaces.data?.find(item => item.id === spaceId);\n const list = useLoad(signal => spaceId ? host.documents(spaceId, { signal }) : Promise.resolve([]), [host, spaceId]);\n const doc = useLoad(signal => here.documentId ? host.document(here.documentId, { signal }) : Promise.resolve(null), [host, here.documentId]);\n const versions = useLoad(signal => here.documentId ? host.versions(here.documentId, { signal }) : Promise.resolve([]), [host, here.documentId]);\n const content = useLoad(signal => here.documentId ? host.content(here.documentId, versionId, { signal }) : Promise.resolve(null), [host, here.documentId, versionId]);\n\n const shown = (list.data ?? []).filter(item => matches(item, query, kind));\n const date = (iso: string) => new Intl.DateTimeFormat(language, { day: 'numeric', month: 'short', year: 'numeric', hour: '2-digit', minute: '2-digit' }).format(new Date(iso));\n const size = (bytes: number) => bytes < 1024 ? `${bytes} B` : bytes < 1048576 ? `${(bytes / 1024).toFixed(0)} KB` : `${(bytes / 1048576).toFixed(1)} MB`;\n const failed = (retry: () => void) => <div className=\"w100n-docs-note\">{t.failed}<button type=\"button\" onClick={retry}>{t.retry}</button></div>;\n const open = (documentId: string) => { setOutline([]); setTab('outline'); go({ spaceId, documentId }); };\n\n let stage: ReactNode = <div className=\"w100n-docs-empty\"><FileText aria-hidden />{t.pick}</div>;\n if (here.documentId) {\n if (doc.error || content.error) stage = failed(() => { doc.retry(); content.retry(); });\n else if (!doc.data || !content.data) stage = <div className=\"w100n-docs-empty\">{t.loading}</div>;\n else if (doc.data.kind === 'markdown') stage = <MarkdownView bytes={content.data} onOutline={setOutline} />;\n else if (doc.data.kind === 'docx') stage = <DocxView bytes={content.data} onOutline={setOutline} failed={t.failed} />;\n else if (doc.data.kind === 'pdf') stage = <PdfView bytes={content.data} worker={host.pdfWorker} onOutline={setOutline} failed={t.failed} />;\n else if (doc.data.kind === 'slides') stage = <SlidesView bytes={content.data} title={doc.data.name} />;\n else stage = <div className=\"w100n-docs-empty\">{t.unsupported}</div>;\n }\n\n const panelTabs: [Tab, LucideIcon, string][] = [['outline', ListTree, t.outline], ['versions', History, t.versions], ['details', Info, t.details]];\n return <div className=\"w100n-docs\" data-theme={theme}>\n <header className=\"w100n-docs-bar w100n-docs-island\">\n {start}\n <button type=\"button\" className=\"w100n-docs-icon\" onClick={() => setListOpen(!listOpen)} aria-label={listOpen ? t.closeList : t.openList} title={listOpen ? t.closeList : t.openList}>\n {listOpen ? <PanelLeftClose /> : <PanelLeftOpen />}\n </button>\n <strong className=\"w100n-docs-title\">{doc.data?.name ?? t.documents}</strong>\n {doc.data && <span className=\"w100n-docs-badge\" data-kind={doc.data.kind}>{t.kinds[doc.data.kind]}</span>}\n {versionId && <span className=\"w100n-docs-badge\">{versions.data?.find(v => v.id === versionId) && date(versions.data.find(v => v.id === versionId)!.createdAt)}</span>}\n {end && <div className=\"w100n-docs-end\">{end}</div>}\n </header>\n <div className=\"w100n-docs-body\">\n {listOpen && <aside className=\"w100n-docs-list w100n-docs-island\" aria-label={t.documents}>\n <div className=\"w100n-docs-picker\">\n <button type=\"button\" className=\"w100n-docs-field\" aria-haspopup=\"listbox\" aria-expanded={picking} onClick={() => setPicking(!picking)}>\n <span className=\"w100n-docs-dot\" style={{ background: space?.color ?? undefined }} />{space?.name ?? t.space}<ChevronDown aria-hidden />\n </button>\n {picking && <ul role=\"listbox\" className=\"w100n-docs-menu\">{(spaces.data ?? []).map(item => <li key={item.id}>\n <button type=\"button\" role=\"option\" aria-selected={item.id === spaceId} onClick={() => { setPicking(false); go({ spaceId: item.id, documentId: null }); }}>\n <span className=\"w100n-docs-dot\" style={{ background: item.color ?? undefined }} />{item.name}\n </button></li>)}</ul>}\n </div>\n <label className=\"w100n-docs-field w100n-docs-search\"><Search aria-hidden /><input value={query} onChange={event => setQuery(event.target.value)} placeholder={t.search} aria-label={t.search} /></label>\n <div className=\"w100n-docs-chips\" role=\"group\">{(['all', ...kinds] as const).map(item => <button key={item} type=\"button\" aria-pressed={kind === item} onClick={() => setKind(item)}>{item === 'all' ? t.all : t.kinds[item]}</button>)}</div>\n <div className=\"w100n-docs-cards\">\n {list.error && failed(list.retry)}\n {list.loading && !list.data && <p className=\"w100n-docs-muted\">{t.loading}</p>}\n {list.data && !shown.length && <p className=\"w100n-docs-muted\">{list.data.length ? t.nothing : t.empty}</p>}\n {shown.map(item => {\n const Icon = icons[item.kind];\n return <button key={item.id} type=\"button\" className=\"w100n-docs-card\" aria-current={item.id === here.documentId} onClick={() => open(item.id)}>\n {item.thumbnailUrl ? <img src={item.thumbnailUrl} alt=\"\" className=\"w100n-docs-thumb\" /> : <span className=\"w100n-docs-thumb\" data-kind={item.kind}><Icon aria-hidden /></span>}\n <span className=\"w100n-docs-card-text\"><b>{item.name}</b><small>{t.kinds[item.kind]} · {date(item.updatedAt)}</small></span>\n </button>;\n })}\n </div>\n </aside>}\n <main className=\"w100n-docs-stage\">{stage}</main>\n {doc.data && <aside className=\"w100n-docs-panel w100n-docs-island\">\n <div className=\"w100n-docs-tabs\" role=\"tablist\">{panelTabs.map(([key, Icon, label]) =>\n <button key={key} type=\"button\" role=\"tab\" aria-selected={tab === key} onClick={() => setTab(key)}><Icon aria-hidden />{label}</button>)}</div>\n {tab === 'outline' && (outline.length ? <nav className=\"w100n-docs-outline\">{outline.map(item =>\n <button key={item.id} type=\"button\" data-level={item.level} onClick={() => document.getElementById(item.id)?.scrollIntoView({ behavior: 'smooth', block: 'start' })}>{item.text}</button>)}</nav>\n : <p className=\"w100n-docs-muted\">{t.noOutline}</p>)}\n {tab === 'versions' && <div className=\"w100n-docs-versions\">\n {versions.error && failed(versions.retry)}\n {(versions.data ?? []).map(item => <button key={item.id} type=\"button\" aria-pressed={(versionId ?? 'current') === item.id || (!versionId && item.current)}\n onClick={() => setVersion({ documentId: here.documentId, id: item.current ? null : item.id })}>\n <b>{date(item.createdAt)}{item.current && <span className=\"w100n-docs-badge\">{t.current}</span>}</b>\n <small>{[item.author?.name, size(item.size), item.note].filter(Boolean).join(' · ')}</small>\n </button>)}\n </div>}\n {tab === 'details' && <dl className=\"w100n-docs-details\">\n <dt>{t.kind}</dt><dd>{t.kinds[doc.data.kind]}</dd>\n <dt>{t.size}</dt><dd>{size(doc.data.size)}</dd>\n <dt>{t.updated}</dt><dd>{date(doc.data.updatedAt)}</dd>\n {doc.data.updatedBy && <><dt>{t.by}</dt><dd>{doc.data.updatedBy.name}</dd></>}\n <dt>{t.rights}</dt><dd>{[doc.data.rights.view && t.view, doc.data.rights.comment && t.comment, doc.data.rights.edit && t.edit].filter(Boolean).join(', ')}</dd>\n </dl>}\n </aside>}\n </div>\n </div>;\n}\n","import type { DocumentKind } from './types';\n\nconst byExtension: Record<string, DocumentKind> = {\n docx: 'docx', md: 'markdown', markdown: 'markdown', pdf: 'pdf', xlsx: 'sheet', csv: 'sheet', html: 'slides', htm: 'slides',\n};\n\nconst byMime: Record<string, DocumentKind> = {\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'docx',\n 'text/markdown': 'markdown',\n 'application/pdf': 'pdf',\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'sheet',\n 'text/csv': 'sheet',\n 'text/html': 'slides',\n};\n\nexport const kinds: DocumentKind[] = ['docx', 'markdown', 'pdf', 'sheet', 'slides'];\n\nexport function kindOf(name: string, mimeType?: string | null): DocumentKind | null {\n const extension = name.includes('.') ? name.split('.').pop()!.toLowerCase() : '';\n return byExtension[extension] ?? (mimeType ? byMime[mimeType.split(';')[0].trim().toLowerCase()] : undefined) ?? null;\n}\n\nexport function matches(doc: { name: string; kind: DocumentKind }, query: string, kind: DocumentKind | 'all') {\n const words = query.toLocaleLowerCase().split(/\\s+/).filter(Boolean);\n return (kind === 'all' || doc.kind === kind) && words.every(word => doc.name.toLocaleLowerCase().includes(word));\n}\n","import type { DocumentKind, Language } from './types';\n\nconst en = {\n documents: 'Documents', search: 'Search documents', all: 'All', empty: 'No documents here yet', nothing: 'Nothing matches the search',\n space: 'Project', pick: 'Choose a document on the left', closeList: 'Hide the list', openList: 'Show the list',\n outline: 'Outline', versions: 'Versions', details: 'Details', noOutline: 'This document has no headings', current: 'Current',\n size: 'Size', updated: 'Updated', by: 'By', kind: 'Format', rights: 'You can', view: 'View', comment: 'Comment', edit: 'Edit',\n failed: 'Could not load', retry: 'Try again', loading: 'Loading', sheet: 'Sheet', unsupported: 'This file cannot be shown yet',\n kinds: { docx: 'DOCX', markdown: 'Markdown', pdf: 'PDF', sheet: 'Sheets', slides: 'Slides' } satisfies Record<DocumentKind, string>,\n};\n\nexport type Text = typeof en;\n\nconst pl: Text = {\n documents: 'Dokumenty', search: 'Szukaj dokumentów', all: 'Wszystkie', empty: 'Nie ma tu jeszcze dokumentów', nothing: 'Nic nie pasuje do wyszukiwania',\n space: 'Projekt', pick: 'Wybierz dokument po lewej', closeList: 'Ukryj listę', openList: 'Pokaż listę',\n outline: 'Spis treści', versions: 'Wersje', details: 'Szczegóły', noOutline: 'Ten dokument nie ma nagłówków', current: 'Bieżąca',\n size: 'Rozmiar', updated: 'Zmieniono', by: 'Autor', kind: 'Format', rights: 'Możesz', view: 'Oglądać', comment: 'Komentować', edit: 'Edytować',\n failed: 'Nie udało się wczytać', retry: 'Spróbuj ponownie', loading: 'Wczytywanie', sheet: 'Arkusz', unsupported: 'Tego pliku nie da się jeszcze pokazać',\n kinds: { docx: 'DOCX', markdown: 'Markdown', pdf: 'PDF', sheet: 'Arkusze', slides: 'Slajdy' },\n};\n\nconst uk: Text = {\n documents: 'Документи', search: 'Пошук документів', all: 'Усі', empty: 'Тут ще немає документів', nothing: 'Нічого не знайдено',\n space: 'Проєкт', pick: 'Виберіть документ ліворуч', closeList: 'Сховати список', openList: 'Показати список',\n outline: 'Зміст', versions: 'Версії', details: 'Деталі', noOutline: 'У документі немає заголовків', current: 'Поточна',\n size: 'Розмір', updated: 'Змінено', by: 'Автор', kind: 'Формат', rights: 'Ви можете', view: 'Дивитися', comment: 'Коментувати', edit: 'Правити',\n failed: 'Не вдалося завантажити', retry: 'Спробувати ще', loading: 'Завантаження', sheet: 'Аркуш', unsupported: 'Цей файл поки не показується',\n kinds: { docx: 'DOCX', markdown: 'Markdown', pdf: 'PDF', sheet: 'Таблиці', slides: 'Слайди' },\n};\n\nexport const texts: Record<Language, Text> = { en, pl, uk };\n","import { useEffect, useState } from 'react';\n\nexport type Loaded<T> = { data: T | null; error: Error | null; loading: boolean; retry: () => void };\n\nexport function useLoad<T>(load: (signal: AbortSignal) => Promise<T>, key: unknown[]): Loaded<T> {\n const [state, setState] = useState<{ data: T | null; error: Error | null; loading: boolean }>({ data: null, error: null, loading: true });\n const [attempt, setAttempt] = useState(0);\n useEffect(() => {\n const controller = new AbortController();\n setState(current => ({ ...current, loading: true, error: null }));\n load(controller.signal).then(\n data => { if (!controller.signal.aborted) setState({ data, error: null, loading: false }); },\n error => { if (!controller.signal.aborted) setState({ data: null, error: error instanceof Error ? error : new Error(String(error)), loading: false }); },\n );\n return () => controller.abort();\n }, [...key, attempt]);\n return { ...state, retry: () => setAttempt(n => n + 1) };\n}\n","import { useLayoutEffect, useRef, useState } from 'react';\nimport { collect, type Heading } from './headings';\n\nexport default function DocxView({ bytes, onOutline, failed }: { bytes: ArrayBuffer; onOutline: (headings: Heading[]) => void; failed: string }) {\n const box = useRef<HTMLDivElement>(null);\n const [error, setError] = useState(false);\n useLayoutEffect(() => {\n let live = true;\n let width = 0;\n const root = box.current!;\n const fit = () => {\n const wrapper = root.querySelector<HTMLElement>('.w100n-docx-wrapper');\n if (wrapper && width) wrapper.style.zoom = String(Math.min(1, root.clientWidth / width));\n };\n const watch = new ResizeObserver(fit);\n root.replaceChildren();\n setError(false);\n import('docx-preview')\n .then(({ renderAsync }) => renderAsync(bytes, root, undefined, { inWrapper: true, className: 'w100n-docx', ignoreLastRenderedPageBreak: true }))\n .then(() => {\n if (!live) return;\n width = Math.max(0, ...[...root.querySelectorAll<HTMLElement>('section.w100n-docx')].map(page => page.offsetWidth));\n fit();\n watch.observe(root);\n onOutline(collect(root, '[class*=\"heading\"]', el => Number(/heading(\\d)/i.exec(el.className)?.[1] ?? 1)));\n })\n .catch(() => { if (live) setError(true); });\n return () => { live = false; watch.disconnect(); };\n }, [bytes, onOutline]);\n return <>{error && <p className=\"w100n-docs-note\">{failed}</p>}<div ref={box} className=\"w100n-docs-docx\" /></>;\n}\n","export type Heading = { id: string; level: number; text: string };\n\nlet last = 0;\n\nexport function collect(root: HTMLElement, selector: string, level: (el: Element) => number = el => Number(el.tagName.slice(1))): Heading[] {\n return [...root.querySelectorAll(selector)].flatMap(el => {\n const text = el.textContent?.trim() ?? '';\n if (!text) return [];\n if (!el.id) el.id = `w100n-docs-h${++last}`;\n return [{ id: el.id, level: Math.min(3, Math.max(1, level(el) || 1)), text }];\n });\n}\n","import DOMPurify from 'dompurify';\nimport { marked } from 'marked';\nimport { useLayoutEffect, useRef } from 'react';\nimport { collect, type Heading } from './headings';\n\nexport default function MarkdownView({ bytes, onOutline }: { bytes: ArrayBuffer; onOutline: (headings: Heading[]) => void }) {\n const box = useRef<HTMLElement>(null);\n useLayoutEffect(() => {\n const root = box.current!;\n root.innerHTML = DOMPurify.sanitize(marked.parse(new TextDecoder().decode(bytes), { async: false }));\n onOutline(collect(root, 'h1, h2, h3'));\n }, [bytes, onOutline]);\n return <article ref={box} className=\"w100n-docs-page w100n-docs-prose\" />;\n}\n","import { useEffect, useRef, useState } from 'react';\nimport type { Heading } from './headings';\n\ntype Outline = { title: string; dest: string | unknown[] | null; items: Outline[] };\n\nlet last = 0;\n\nexport default function PdfView({ bytes, worker, onOutline, failed }: { bytes: ArrayBuffer; worker?: () => Worker; onOutline: (headings: Heading[]) => void; failed: string }) {\n const box = useRef<HTMLDivElement>(null);\n const [error, setError] = useState(false);\n useEffect(() => {\n const root = box.current!;\n const prefix = `w100n-docs-p${++last}`;\n let stop = false;\n let close = () => {};\n root.replaceChildren();\n setError(false);\n (async () => {\n const pdfjs = await import('pdfjs-dist');\n if (worker) pdfjs.GlobalWorkerOptions.workerPort ??= worker();\n const task = pdfjs.getDocument({ data: new Uint8Array(bytes.slice(0)) });\n close = () => { void task.destroy(); };\n const pdf = await task.promise;\n const width = Math.max(320, root.clientWidth - 48);\n for (let n = 1; n <= pdf.numPages && !stop; n++) {\n const page = await pdf.getPage(n);\n const scale = Math.min(2, width / page.getViewport({ scale: 1 }).width);\n const viewport = page.getViewport({ scale: scale * window.devicePixelRatio });\n const canvas = document.createElement('canvas');\n canvas.id = `${prefix}-${n}`;\n canvas.className = 'w100n-docs-sheet';\n canvas.width = viewport.width;\n canvas.height = viewport.height;\n canvas.style.width = `${viewport.width / window.devicePixelRatio}px`;\n root.append(canvas);\n await page.render({ canvas, canvasContext: canvas.getContext('2d')!, viewport }).promise;\n }\n const flat = async (items: Outline[], level: number): Promise<Heading[]> => (await Promise.all(items.map(async item => {\n const dest = typeof item.dest === 'string' ? await pdf.getDestination(item.dest) : item.dest;\n const ref = Array.isArray(dest) ? dest[0] : null;\n const index = ref && typeof ref === 'object' ? await pdf.getPageIndex(ref as never) : null;\n const here = index === null ? [] : [{ id: `${prefix}-${index + 1}`, level, text: item.title }];\n return [...here, ...(level < 3 ? await flat(item.items ?? [], level + 1) : [])];\n }))).flat();\n if (!stop) onOutline(await flat(((await pdf.getOutline()) ?? []) as Outline[], 1));\n })().catch(() => { if (!stop) setError(true); });\n return () => { stop = true; close(); };\n }, [bytes, worker, onOutline]);\n return <>{error && <p className=\"w100n-docs-note\">{failed}</p>}<div ref={box} className=\"w100n-docs-pdf\" /></>;\n}\n","export default function SlidesView({ bytes, title }: { bytes: ArrayBuffer; title: string }) {\n return <iframe className=\"w100n-docs-slides\" sandbox=\"allow-scripts\" title={title} srcDoc={new TextDecoder().decode(bytes)} />;\n}\n"],"mappings":"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","names":["import_react","import_react","import_react","import_jsx_runtime","DOMPurify","import_react","import_jsx_runtime","last","import_jsx_runtime","import_jsx_runtime"]}