@inkandswitch/patchwork-pkg-base 0.0.41 → 0.0.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/packages/account/dist/{InlineContactAvatar-TVDLE2AV.js → InlineContactAvatar-6UAAJ73R.js} +2 -1
- package/packages/account/dist/InlineContactAvatar-6UAAJ73R.js.map +7 -0
- package/packages/account/dist/index.js +1 -1
- package/packages/chat/dist/{ChatRoot-DQkQQvPO.js → ChatRoot-WdCS4aLg.js} +3001 -2807
- package/packages/chat/dist/{context-tool-BuY29sJF.js → context-tool-KkwLFr2k.js} +2 -2
- package/packages/chat/dist/{index-NiYOPQzY.js → index-P8UuZ1jj.js} +3 -3
- package/packages/chat/dist/index.js +1 -1
- package/packages/chat/dist/{tool-He3mRTzT.js → tool-DWqQOW59.js} +2 -2
- package/packages/chat/package.json +1 -1
- package/packages/codemirror-base/dist/chunk-H5POLO74.js +2658 -0
- package/packages/codemirror-base/dist/chunk-H5POLO74.js.map +7 -0
- package/packages/codemirror-base/dist/lib/codemirror.js +1 -1
- package/packages/codemirror-base/dist/tool.js +9 -5
- package/packages/codemirror-base/dist/tool.js.map +2 -2
- package/packages/codemirror-base/package.json +1 -1
- package/packages/codemirror-markdown/dist/extensions/markdown.js +0 -94
- package/packages/codemirror-markdown/dist/extensions/markdown.js.map +3 -3
- package/packages/drafts/dist/assets/{DraftOverlayProvider-B0Mtq1UF.js → DraftOverlayProvider-VYKlzOy1.js} +85 -25
- package/packages/drafts/dist/assets/DraftOverlayProvider-VYKlzOy1.js.map +1 -0
- package/packages/drafts/dist/assets/{DraftListProvider-D41q9O5B.js → DraftStateProvider-DX8b_RgQ.js} +270 -39
- package/packages/drafts/dist/assets/DraftStateProvider-DX8b_RgQ.js.map +1 -0
- package/packages/drafts/dist/assets/{clone-policy-C4pVv5sr.js → clone-policy-CIdEhg7W.js} +5 -2
- package/packages/drafts/dist/assets/{clone-policy-C4pVv5sr.js.map → clone-policy-CIdEhg7W.js.map} +1 -1
- package/packages/drafts/dist/assets/draft-docs-Bi8K1y3a.js +554 -0
- package/packages/drafts/dist/assets/draft-docs-Bi8K1y3a.js.map +1 -0
- package/packages/drafts/dist/assets/main-BR_tW0sp.js +3105 -0
- package/packages/drafts/dist/assets/main-BR_tW0sp.js.map +1 -0
- package/packages/drafts/dist/index.js +14 -14
- package/packages/drafts/dist/index.js.map +1 -1
- package/packages/drafts/package.json +1 -1
- package/packages/raw/raw-editor.js +26 -11
- package/packages/threepane/dist/IsolatedDocumentArea-2JIBFDOX.js +2 -0
- package/packages/threepane/dist/{PatchworkFrame-4AEBOBRE.js → PatchworkFrame-P5P6JTJE.js} +2 -2
- package/packages/threepane/dist/chunk-CGHYPNSB.js +972 -0
- package/packages/threepane/dist/chunk-CGHYPNSB.js.map +7 -0
- package/packages/threepane/dist/index.js +1 -1
- package/packages/tldraw4/dist/tool.js +61 -10
- package/packages/tldraw4/dist/tool.js.map +2 -2
- package/packages/tldraw4/package.json +2 -2
- package/packages/account/dist/InlineContactAvatar-TVDLE2AV.js.map +0 -7
- package/packages/codemirror-base/dist/chunk-5IG5TKXV.js +0 -795
- package/packages/codemirror-base/dist/chunk-5IG5TKXV.js.map +0 -7
- package/packages/drafts/dist/assets/DraftListProvider-D41q9O5B.js.map +0 -1
- package/packages/drafts/dist/assets/DraftOverlayProvider-B0Mtq1UF.js.map +0 -1
- package/packages/drafts/dist/assets/main-Cp8VsNHh.js +0 -2331
- package/packages/drafts/dist/assets/main-Cp8VsNHh.js.map +0 -1
- package/packages/threepane/dist/IsolatedDocumentArea-MZBBRFMY.js +0 -2
- package/packages/threepane/dist/chunk-HNLVJAZZ.js +0 -972
- package/packages/threepane/dist/chunk-HNLVJAZZ.js.map +0 -7
- /package/packages/threepane/dist/{IsolatedDocumentArea-MZBBRFMY.js.map → IsolatedDocumentArea-2JIBFDOX.js.map} +0 -0
- /package/packages/threepane/dist/{PatchworkFrame-4AEBOBRE.js.map → PatchworkFrame-P5P6JTJE.js.map} +0 -0
|
@@ -1,2331 +0,0 @@
|
|
|
1
|
-
(function() {
|
|
2
|
-
"use strict";
|
|
3
|
-
try {
|
|
4
|
-
if (typeof document != "undefined") {
|
|
5
|
-
var elementStyle = document.createElement("style");
|
|
6
|
-
elementStyle.appendChild(document.createTextNode(`@layer package {
|
|
7
|
-
:root,
|
|
8
|
-
:host,
|
|
9
|
-
[theme] {
|
|
10
|
-
--drafts-fg: var(--studio-line, black);
|
|
11
|
-
--drafts-muted-fg: var(--studio-line-offset-50, #6b7280);
|
|
12
|
-
--drafts-faint-fg: var(--studio-line-offset-40, #9ca3af);
|
|
13
|
-
--drafts-bg: var(--studio-fill, white);
|
|
14
|
-
--drafts-border: var(--studio-fill-offset-20, #e5e7eb);
|
|
15
|
-
--drafts-hover-bg: var(--studio-fill-offset-10, #f9fafb);
|
|
16
|
-
--drafts-selected-bg: var(--studio-fill-offset-20, #eef2ff);
|
|
17
|
-
--drafts-font: var(--studio-family-sans, system-ui, sans-serif);
|
|
18
|
-
--drafts-mono: var(--studio-family-code, ui-monospace, monospace);
|
|
19
|
-
--drafts-primary: var(--studio-primary-fill, var(--studio-primary, #3b82f6));
|
|
20
|
-
--drafts-primary-line: var(--studio-primary-line, var(--studio-fill, white));
|
|
21
|
-
--drafts-primary-fg: var(--drafts-primary-line);
|
|
22
|
-
--drafts-warning: var(--studio-warning-fill, var(--studio-warning, #f59e0b));
|
|
23
|
-
--drafts-warning-fg: var(--studio-warning-line, var(--studio-fill, white));
|
|
24
|
-
--drafts-radius: var(--studio-radius-md, 0.5rem);
|
|
25
|
-
--drafts-radius-sm: var(--studio-radius-sm, 0.25rem);
|
|
26
|
-
--drafts-shadow-sm: var(--studio-shadow-sm, 0 1px 2px 0 rgb(0 0 0 / 0.05));
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
.drafts-panel {
|
|
31
|
-
height: 100%;
|
|
32
|
-
display: flex;
|
|
33
|
-
flex-direction: column;
|
|
34
|
-
padding: 0.5rem;
|
|
35
|
-
gap: 0.5rem;
|
|
36
|
-
font-family: var(--drafts-font);
|
|
37
|
-
color: var(--drafts-fg);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
.drafts-empty {
|
|
41
|
-
font-size: 0.75rem;
|
|
42
|
-
color: var(--drafts-faint-fg);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
.drafts-list {
|
|
46
|
-
display: flex;
|
|
47
|
-
flex-direction: column;
|
|
48
|
-
gap: 0.25rem;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
.drafts-actions {
|
|
52
|
-
display: flex;
|
|
53
|
-
flex-direction: column;
|
|
54
|
-
align-items: flex-end;
|
|
55
|
-
gap: 0.25rem;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/* The panel-level actions row above the cards (the "New draft" button). */
|
|
59
|
-
.drafts-actions--top {
|
|
60
|
-
align-items: stretch;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
.drafts-hint {
|
|
64
|
-
font-size: 0.75rem;
|
|
65
|
-
font-style: italic;
|
|
66
|
-
color: var(--drafts-faint-fg);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/* Drop target for a version dragged out of a history timeline (group row or
|
|
70
|
-
scrubber sticker); only rendered while such a drag is in flight. Dropping
|
|
71
|
-
forks a new draft at that version. */
|
|
72
|
-
.drafts-dropzone {
|
|
73
|
-
align-self: stretch;
|
|
74
|
-
padding: 0.75rem 0.5rem;
|
|
75
|
-
border: 1.5px dashed var(--drafts-primary);
|
|
76
|
-
border-radius: var(--drafts-radius-sm);
|
|
77
|
-
font-size: 0.75rem;
|
|
78
|
-
color: var(--drafts-primary);
|
|
79
|
-
text-align: center;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
.drafts-dropzone[data-over] {
|
|
83
|
-
background: color-mix(in srgb, var(--drafts-primary) 12%, transparent);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
.drafts-btn {
|
|
87
|
-
font-family: inherit;
|
|
88
|
-
font-size: 0.875rem;
|
|
89
|
-
line-height: 1.25rem;
|
|
90
|
-
padding: 0.25rem 0.75rem;
|
|
91
|
-
border: 1px solid transparent;
|
|
92
|
-
border-radius: var(--drafts-radius-sm);
|
|
93
|
-
cursor: pointer;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
.drafts-btn:not(:disabled):hover {
|
|
97
|
-
filter: brightness(0.95);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
.drafts-btn:disabled {
|
|
101
|
-
opacity: 0.5;
|
|
102
|
-
cursor: not-allowed;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
.drafts-btn--primary {
|
|
106
|
-
background: var(--drafts-primary);
|
|
107
|
-
color: var(--drafts-primary-fg);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
.drafts-btn--warning {
|
|
111
|
-
background: var(--drafts-warning);
|
|
112
|
-
color: var(--drafts-warning-fg);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
.drafts-btn--ghost {
|
|
116
|
-
background: transparent;
|
|
117
|
-
border-color: var(--drafts-border);
|
|
118
|
-
color: var(--drafts-fg);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
.draft-card {
|
|
122
|
-
background: var(--drafts-bg);
|
|
123
|
-
border: 1px solid var(--drafts-border);
|
|
124
|
-
border-radius: var(--drafts-radius);
|
|
125
|
-
box-shadow: var(--drafts-shadow-sm);
|
|
126
|
-
overflow: hidden;
|
|
127
|
-
transition:
|
|
128
|
-
border-color 0.15s ease,
|
|
129
|
-
box-shadow 0.15s ease;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
.draft-card[data-selected] {
|
|
133
|
-
border-color: var(--drafts-primary-line);
|
|
134
|
-
box-shadow: 0 0 0 1px var(--drafts-primary-line);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
.draft-card-header {
|
|
138
|
-
/* The header is a div (a rename input can't nest in a button), which,
|
|
139
|
-
unlike a button, doesn't default to border-box — without this the
|
|
140
|
-
padding pushes it past the card edge. */
|
|
141
|
-
box-sizing: border-box;
|
|
142
|
-
display: flex;
|
|
143
|
-
flex-direction: column;
|
|
144
|
-
gap: 0.25rem;
|
|
145
|
-
width: 100%;
|
|
146
|
-
padding: 0.5rem;
|
|
147
|
-
text-align: left;
|
|
148
|
-
background: transparent;
|
|
149
|
-
border: none;
|
|
150
|
-
cursor: pointer;
|
|
151
|
-
font-family: inherit;
|
|
152
|
-
color: inherit;
|
|
153
|
-
transition: background 0.15s ease;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
.draft-card-header:hover {
|
|
157
|
-
background: var(--drafts-hover-bg);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
.draft-card[data-selected] .draft-card-header {
|
|
161
|
-
background: var(--drafts-selected-bg);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
.draft-card-title {
|
|
165
|
-
display: flex;
|
|
166
|
-
align-items: center;
|
|
167
|
-
gap: 0.5rem;
|
|
168
|
-
font-size: 0.875rem;
|
|
169
|
-
font-weight: 500;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
.draft-name {
|
|
173
|
-
overflow: hidden;
|
|
174
|
-
text-overflow: ellipsis;
|
|
175
|
-
white-space: nowrap;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/* Inline rename editor, swapped in for .draft-name on double-click. */
|
|
179
|
-
.draft-name-input {
|
|
180
|
-
flex: 1;
|
|
181
|
-
min-width: 0;
|
|
182
|
-
font: inherit;
|
|
183
|
-
color: inherit;
|
|
184
|
-
padding: 0 0.25rem;
|
|
185
|
-
margin: 0;
|
|
186
|
-
background: var(--drafts-bg);
|
|
187
|
-
border: 1px solid var(--drafts-primary);
|
|
188
|
-
border-radius: var(--drafts-radius-sm);
|
|
189
|
-
outline: none;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
.draft-badge {
|
|
193
|
-
flex-shrink: 0;
|
|
194
|
-
font-size: 0.625rem;
|
|
195
|
-
line-height: 1;
|
|
196
|
-
padding: 0.125rem 0.375rem;
|
|
197
|
-
border-radius: var(--studio-radius-round, 9999px);
|
|
198
|
-
background: var(--drafts-primary);
|
|
199
|
-
color: var(--drafts-primary-fg);
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
.draft-card-url {
|
|
203
|
-
font-size: 0.75rem;
|
|
204
|
-
font-family: var(--drafts-mono);
|
|
205
|
-
color: var(--drafts-muted-fg);
|
|
206
|
-
word-break: break-all;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
.draft-card-meta {
|
|
210
|
-
font-size: 0.75rem;
|
|
211
|
-
color: var(--drafts-faint-fg);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
.draft-card-changes {
|
|
215
|
-
display: flex;
|
|
216
|
-
flex-direction: column;
|
|
217
|
-
gap: 0.125rem;
|
|
218
|
-
border-top: 1px solid var(--drafts-border);
|
|
219
|
-
padding: 0.25rem;
|
|
220
|
-
max-height: 12rem;
|
|
221
|
-
overflow-y: auto;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
/* The selected card gets room to show more history; cards with little
|
|
225
|
-
history stay at their natural height. */
|
|
226
|
-
.draft-card[data-selected] .draft-card-changes {
|
|
227
|
-
max-height: 32rem;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
/* Card footer while the timeline is pinned: sits under the (scrollable)
|
|
231
|
-
changes area, so it stays reachable however long the history is. */
|
|
232
|
-
.draft-card-return {
|
|
233
|
-
display: block;
|
|
234
|
-
width: 100%;
|
|
235
|
-
padding: 0.375rem 0.5rem;
|
|
236
|
-
border: none;
|
|
237
|
-
border-top: 1px solid var(--drafts-border);
|
|
238
|
-
background: transparent;
|
|
239
|
-
font-family: inherit;
|
|
240
|
-
font-size: 0.75rem;
|
|
241
|
-
color: var(--drafts-primary);
|
|
242
|
-
text-align: center;
|
|
243
|
-
cursor: pointer;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
.draft-card-return:hover {
|
|
247
|
-
background: var(--drafts-hover-bg);
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
.draft-changes-empty {
|
|
251
|
-
font-size: 0.75rem;
|
|
252
|
-
color: var(--drafts-faint-fg);
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
.draft-change-row {
|
|
256
|
-
display: flex;
|
|
257
|
-
flex-direction: column;
|
|
258
|
-
gap: 0.125rem;
|
|
259
|
-
width: 100%;
|
|
260
|
-
padding: 0.25rem 0.5rem;
|
|
261
|
-
border: none;
|
|
262
|
-
border-radius: var(--drafts-radius-sm);
|
|
263
|
-
background: transparent;
|
|
264
|
-
font-family: inherit;
|
|
265
|
-
font-size: 0.75rem;
|
|
266
|
-
text-align: left;
|
|
267
|
-
color: inherit;
|
|
268
|
-
cursor: pointer;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
.draft-change-line {
|
|
272
|
-
display: flex;
|
|
273
|
-
align-items: baseline;
|
|
274
|
-
gap: 0.5rem;
|
|
275
|
-
width: 100%;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
.draft-change-row:hover {
|
|
279
|
-
background: var(--drafts-hover-bg);
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
.draft-change-row[data-selected] {
|
|
283
|
-
background: var(--drafts-selected-bg);
|
|
284
|
-
box-shadow: inset 0 0 0 1px var(--drafts-primary);
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
.draft-change-time {
|
|
288
|
-
flex: none;
|
|
289
|
-
color: var(--drafts-muted-fg);
|
|
290
|
-
white-space: nowrap;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
.draft-change-doc {
|
|
294
|
-
flex: 0 1 auto;
|
|
295
|
-
min-width: 0;
|
|
296
|
-
font-weight: 600;
|
|
297
|
-
color: var(--drafts-fg);
|
|
298
|
-
overflow: hidden;
|
|
299
|
-
text-overflow: ellipsis;
|
|
300
|
-
white-space: nowrap;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
.draft-change-msg {
|
|
304
|
-
flex: 1 1 auto;
|
|
305
|
-
min-width: 0;
|
|
306
|
-
color: var(--drafts-fg);
|
|
307
|
-
overflow: hidden;
|
|
308
|
-
text-overflow: ellipsis;
|
|
309
|
-
white-space: nowrap;
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
.draft-change-hash {
|
|
313
|
-
font-family: var(--drafts-mono);
|
|
314
|
-
font-size: 0.625rem;
|
|
315
|
-
color: var(--drafts-faint-fg);
|
|
316
|
-
word-break: break-all;
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
/* ---- Grouped history: one non-expandable row per time window ---- */
|
|
320
|
-
|
|
321
|
-
/* Group row layout: avatar stack, timestamp, flexible spacer, +/- counts.
|
|
322
|
-
The extra vertical padding gives each group a taller scrubber band, so
|
|
323
|
-
per-change stops inside a group are easier to hit. */
|
|
324
|
-
.draft-group-row {
|
|
325
|
-
display: flex;
|
|
326
|
-
align-items: center;
|
|
327
|
-
gap: 0.375rem;
|
|
328
|
-
width: 100%;
|
|
329
|
-
padding: 0.5rem 0.375rem;
|
|
330
|
-
border: none;
|
|
331
|
-
border-radius: var(--drafts-radius-sm);
|
|
332
|
-
background: transparent;
|
|
333
|
-
font-family: inherit;
|
|
334
|
-
font-size: 0.75rem;
|
|
335
|
-
text-align: left;
|
|
336
|
-
color: inherit;
|
|
337
|
-
cursor: pointer;
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
/* Group backgrounds stay semi-transparent so the scrubber lines painted
|
|
341
|
-
underneath the rows remain visible through them. */
|
|
342
|
-
.draft-group-row:hover {
|
|
343
|
-
background: color-mix(in srgb, var(--drafts-hover-bg) 60%, transparent);
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
.draft-group-row[data-selected] {
|
|
347
|
-
background: color-mix(in srgb, var(--drafts-selected-bg) 60%, transparent);
|
|
348
|
-
box-shadow: inset 0 0 0 1px var(--drafts-primary);
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
.draft-group-spacer {
|
|
352
|
-
flex: 1 1 auto;
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
.draft-group-time {
|
|
356
|
-
color: var(--drafts-muted-fg);
|
|
357
|
-
white-space: nowrap;
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
/* Author avatars */
|
|
361
|
-
.draft-avatars {
|
|
362
|
-
display: flex;
|
|
363
|
-
align-items: center;
|
|
364
|
-
flex: none;
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
.draft-avatar {
|
|
368
|
-
position: relative;
|
|
369
|
-
flex: none;
|
|
370
|
-
width: 18px;
|
|
371
|
-
height: 18px;
|
|
372
|
-
border-radius: 50%;
|
|
373
|
-
display: flex;
|
|
374
|
-
align-items: center;
|
|
375
|
-
justify-content: center;
|
|
376
|
-
font-size: 9px;
|
|
377
|
-
font-weight: 300;
|
|
378
|
-
color: white;
|
|
379
|
-
user-select: none;
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
.draft-avatar--extra {
|
|
383
|
-
margin-left: -4px;
|
|
384
|
-
font-size: 7px;
|
|
385
|
-
background: var(--drafts-faint-fg);
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
/* ---- Scrubber: the history gutter left of the group rows ---- */
|
|
389
|
-
|
|
390
|
-
/* Two-column body inside the scrollable changes area: gutter + group rows,
|
|
391
|
-
with the indicator overlaid across both. Positioned so the rows'
|
|
392
|
-
offsetTop measurements (used to map changes onto the gutter) are relative
|
|
393
|
-
to this box. Isolated so the indicator's negative-z lines paint above the
|
|
394
|
-
card background yet below the rows (instead of escaping behind the card). */
|
|
395
|
-
.draft-changes-body {
|
|
396
|
-
position: relative;
|
|
397
|
-
isolation: isolate;
|
|
398
|
-
display: flex;
|
|
399
|
-
align-items: stretch;
|
|
400
|
-
gap: 0.25rem;
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
.draft-changes-rows {
|
|
404
|
-
flex: 1 1 auto;
|
|
405
|
-
min-width: 0;
|
|
406
|
-
display: flex;
|
|
407
|
-
flex-direction: column;
|
|
408
|
-
gap: 0.125rem;
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
/* The gutter spans the whole history: top = latest change, bottom = first.
|
|
412
|
-
Purely a visual track — scrubbing starts from the indicator's handles. */
|
|
413
|
-
.draft-scrubber {
|
|
414
|
-
position: relative;
|
|
415
|
-
flex: none;
|
|
416
|
-
width: 16px;
|
|
417
|
-
border-radius: var(--drafts-radius-sm);
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
/* The indicator sits at the head like a calendar's now-line: a dot in the
|
|
421
|
-
gutter plus a line across the rows (the version being looked at). The line
|
|
422
|
-
paints *under* the group rows (negative z-index; the rows' backgrounds are
|
|
423
|
-
semi-transparent), while the handles and the sticker paint above. The box
|
|
424
|
-
itself ignores pointer events so rows stay clickable; the handles
|
|
425
|
-
re-enable them. */
|
|
426
|
-
.draft-scrubber-token {
|
|
427
|
-
--scrub-color: var(--studio-danger, #dc2626);
|
|
428
|
-
position: absolute;
|
|
429
|
-
left: 0;
|
|
430
|
-
right: 0;
|
|
431
|
-
pointer-events: none;
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
/* Nothing pinned: the indicator idles at the top (live latest), drawn
|
|
435
|
-
muted. */
|
|
436
|
-
.draft-scrubber-token[data-live] {
|
|
437
|
-
--scrub-color: var(--drafts-faint-fg);
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
.draft-scrubber-dot {
|
|
441
|
-
position: absolute;
|
|
442
|
-
top: -5px;
|
|
443
|
-
left: 3px;
|
|
444
|
-
width: 10px;
|
|
445
|
-
height: 10px;
|
|
446
|
-
border-radius: 50%;
|
|
447
|
-
background: var(--scrub-color);
|
|
448
|
-
pointer-events: auto;
|
|
449
|
-
cursor: grab;
|
|
450
|
-
touch-action: none;
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
.draft-scrubber-dot:active {
|
|
454
|
-
cursor: grabbing;
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
/* The visible head line, spanning into the rows but painted behind them. */
|
|
458
|
-
.draft-scrubber-line {
|
|
459
|
-
position: absolute;
|
|
460
|
-
top: 0;
|
|
461
|
-
left: 8px;
|
|
462
|
-
right: 0;
|
|
463
|
-
height: 2px;
|
|
464
|
-
margin-top: -1px;
|
|
465
|
-
border-radius: 1px;
|
|
466
|
-
background: var(--scrub-color);
|
|
467
|
-
z-index: -1;
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
/* Invisible grab strip over the line's gutter end; dragging only starts
|
|
471
|
-
from this (or the dot), never from the rows or the bare gutter. */
|
|
472
|
-
.draft-scrubber-edge {
|
|
473
|
-
position: absolute;
|
|
474
|
-
top: -4.5px;
|
|
475
|
-
left: 0;
|
|
476
|
-
width: 16px;
|
|
477
|
-
height: 9px;
|
|
478
|
-
pointer-events: auto;
|
|
479
|
-
cursor: grab;
|
|
480
|
-
touch-action: none;
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
/* While pinned, a chip anchored to the head line overlays the group row's
|
|
484
|
-
time/summary with the exact change the line sits on. Painted above
|
|
485
|
-
everything in the changes body (opaque, topmost z-index) so neither the
|
|
486
|
-
head line nor the row content shows through. Interactive as a drag handle:
|
|
487
|
-
dragging it out of the timeline forks a new draft at that version (which
|
|
488
|
-
is why it takes pointer events, shadowing the row beneath it). */
|
|
489
|
-
.draft-scrubber-sticker {
|
|
490
|
-
position: absolute;
|
|
491
|
-
top: -10px;
|
|
492
|
-
left: calc(16px + 0.25rem);
|
|
493
|
-
right: 0;
|
|
494
|
-
height: 20px;
|
|
495
|
-
z-index: 10;
|
|
496
|
-
display: flex;
|
|
497
|
-
align-items: center;
|
|
498
|
-
gap: 0.375rem;
|
|
499
|
-
padding: 0 0.375rem;
|
|
500
|
-
border: 1px solid var(--scrub-color);
|
|
501
|
-
border-radius: var(--drafts-radius-sm);
|
|
502
|
-
background: var(--drafts-bg);
|
|
503
|
-
font-size: 0.6875rem;
|
|
504
|
-
white-space: nowrap;
|
|
505
|
-
overflow: hidden;
|
|
506
|
-
pointer-events: auto;
|
|
507
|
-
cursor: grab;
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
.draft-scrubber-sticker:active {
|
|
511
|
-
cursor: grabbing;
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
.draft-sticker-time {
|
|
515
|
-
flex: none;
|
|
516
|
-
color: var(--drafts-muted-fg);
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
.draft-sticker-title {
|
|
520
|
-
flex: 0 1 auto;
|
|
521
|
-
min-width: 0;
|
|
522
|
-
font-weight: 600;
|
|
523
|
-
overflow: hidden;
|
|
524
|
-
text-overflow: ellipsis;
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
.draft-sticker-spacer {
|
|
528
|
-
flex: 1 1 auto;
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
/* Edit-size counts */
|
|
532
|
-
.draft-counts {
|
|
533
|
-
display: flex;
|
|
534
|
-
align-items: center;
|
|
535
|
-
gap: 0.375rem;
|
|
536
|
-
flex: none;
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
.draft-count {
|
|
540
|
-
font-size: 0.6875rem;
|
|
541
|
-
font-weight: 300;
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
.draft-count--add {
|
|
545
|
-
color: var(--studio-success, #16a34a);
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
.draft-count--del {
|
|
549
|
-
color: var(--studio-danger, #dc2626);
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
.drafts-version {
|
|
553
|
-
padding: 0.25rem 0.5rem;
|
|
554
|
-
font-family: var(--drafts-mono);
|
|
555
|
-
font-size: 0.625rem;
|
|
556
|
-
color: var(--drafts-faint-fg);
|
|
557
|
-
text-align: right;
|
|
558
|
-
}`));
|
|
559
|
-
document.head.appendChild(elementStyle);
|
|
560
|
-
}
|
|
561
|
-
} catch (e) {
|
|
562
|
-
console.error("vite-plugin-css-injected-by-js", e);
|
|
563
|
-
}
|
|
564
|
-
})();
|
|
565
|
-
import { insert, createComponent, effect, setAttribute, memo, template, addEventListener, use, setStyleProperty, delegateEvents, render } from "solid-js/web";
|
|
566
|
-
import { createContext, createSignal, createEffect, onCleanup, onMount, createMemo, Show, For } from "solid-js";
|
|
567
|
-
import { createStore, reconcile } from "solid-js/store";
|
|
568
|
-
import { decodeHeads, encodeHeads } from "@automerge/automerge-repo/slim";
|
|
569
|
-
import * as Automerge from "@automerge/automerge/slim";
|
|
570
|
-
import { getRegistry, isLoadedPlugin } from "@inkandswitch/patchwork-plugins";
|
|
571
|
-
import { s as subscribe$1 } from "./index-FKZtof6Z.js";
|
|
572
|
-
import "@automerge/automerge-repo";
|
|
573
|
-
function getDefaultExportFromCjs(x) {
|
|
574
|
-
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
|
|
575
|
-
}
|
|
576
|
-
var browser = { exports: {} };
|
|
577
|
-
var ms;
|
|
578
|
-
var hasRequiredMs;
|
|
579
|
-
function requireMs() {
|
|
580
|
-
if (hasRequiredMs) return ms;
|
|
581
|
-
hasRequiredMs = 1;
|
|
582
|
-
var s = 1e3;
|
|
583
|
-
var m = s * 60;
|
|
584
|
-
var h = m * 60;
|
|
585
|
-
var d = h * 24;
|
|
586
|
-
var w = d * 7;
|
|
587
|
-
var y = d * 365.25;
|
|
588
|
-
ms = function(val, options) {
|
|
589
|
-
options = options || {};
|
|
590
|
-
var type = typeof val;
|
|
591
|
-
if (type === "string" && val.length > 0) {
|
|
592
|
-
return parse(val);
|
|
593
|
-
} else if (type === "number" && isFinite(val)) {
|
|
594
|
-
return options.long ? fmtLong(val) : fmtShort(val);
|
|
595
|
-
}
|
|
596
|
-
throw new Error(
|
|
597
|
-
"val is not a non-empty string or a valid number. val=" + JSON.stringify(val)
|
|
598
|
-
);
|
|
599
|
-
};
|
|
600
|
-
function parse(str) {
|
|
601
|
-
str = String(str);
|
|
602
|
-
if (str.length > 100) {
|
|
603
|
-
return;
|
|
604
|
-
}
|
|
605
|
-
var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(
|
|
606
|
-
str
|
|
607
|
-
);
|
|
608
|
-
if (!match) {
|
|
609
|
-
return;
|
|
610
|
-
}
|
|
611
|
-
var n = parseFloat(match[1]);
|
|
612
|
-
var type = (match[2] || "ms").toLowerCase();
|
|
613
|
-
switch (type) {
|
|
614
|
-
case "years":
|
|
615
|
-
case "year":
|
|
616
|
-
case "yrs":
|
|
617
|
-
case "yr":
|
|
618
|
-
case "y":
|
|
619
|
-
return n * y;
|
|
620
|
-
case "weeks":
|
|
621
|
-
case "week":
|
|
622
|
-
case "w":
|
|
623
|
-
return n * w;
|
|
624
|
-
case "days":
|
|
625
|
-
case "day":
|
|
626
|
-
case "d":
|
|
627
|
-
return n * d;
|
|
628
|
-
case "hours":
|
|
629
|
-
case "hour":
|
|
630
|
-
case "hrs":
|
|
631
|
-
case "hr":
|
|
632
|
-
case "h":
|
|
633
|
-
return n * h;
|
|
634
|
-
case "minutes":
|
|
635
|
-
case "minute":
|
|
636
|
-
case "mins":
|
|
637
|
-
case "min":
|
|
638
|
-
case "m":
|
|
639
|
-
return n * m;
|
|
640
|
-
case "seconds":
|
|
641
|
-
case "second":
|
|
642
|
-
case "secs":
|
|
643
|
-
case "sec":
|
|
644
|
-
case "s":
|
|
645
|
-
return n * s;
|
|
646
|
-
case "milliseconds":
|
|
647
|
-
case "millisecond":
|
|
648
|
-
case "msecs":
|
|
649
|
-
case "msec":
|
|
650
|
-
case "ms":
|
|
651
|
-
return n;
|
|
652
|
-
default:
|
|
653
|
-
return void 0;
|
|
654
|
-
}
|
|
655
|
-
}
|
|
656
|
-
function fmtShort(ms2) {
|
|
657
|
-
var msAbs = Math.abs(ms2);
|
|
658
|
-
if (msAbs >= d) {
|
|
659
|
-
return Math.round(ms2 / d) + "d";
|
|
660
|
-
}
|
|
661
|
-
if (msAbs >= h) {
|
|
662
|
-
return Math.round(ms2 / h) + "h";
|
|
663
|
-
}
|
|
664
|
-
if (msAbs >= m) {
|
|
665
|
-
return Math.round(ms2 / m) + "m";
|
|
666
|
-
}
|
|
667
|
-
if (msAbs >= s) {
|
|
668
|
-
return Math.round(ms2 / s) + "s";
|
|
669
|
-
}
|
|
670
|
-
return ms2 + "ms";
|
|
671
|
-
}
|
|
672
|
-
function fmtLong(ms2) {
|
|
673
|
-
var msAbs = Math.abs(ms2);
|
|
674
|
-
if (msAbs >= d) {
|
|
675
|
-
return plural(ms2, msAbs, d, "day");
|
|
676
|
-
}
|
|
677
|
-
if (msAbs >= h) {
|
|
678
|
-
return plural(ms2, msAbs, h, "hour");
|
|
679
|
-
}
|
|
680
|
-
if (msAbs >= m) {
|
|
681
|
-
return plural(ms2, msAbs, m, "minute");
|
|
682
|
-
}
|
|
683
|
-
if (msAbs >= s) {
|
|
684
|
-
return plural(ms2, msAbs, s, "second");
|
|
685
|
-
}
|
|
686
|
-
return ms2 + " ms";
|
|
687
|
-
}
|
|
688
|
-
function plural(ms2, msAbs, n, name) {
|
|
689
|
-
var isPlural = msAbs >= n * 1.5;
|
|
690
|
-
return Math.round(ms2 / n) + " " + name + (isPlural ? "s" : "");
|
|
691
|
-
}
|
|
692
|
-
return ms;
|
|
693
|
-
}
|
|
694
|
-
var common;
|
|
695
|
-
var hasRequiredCommon;
|
|
696
|
-
function requireCommon() {
|
|
697
|
-
if (hasRequiredCommon) return common;
|
|
698
|
-
hasRequiredCommon = 1;
|
|
699
|
-
function setup(env) {
|
|
700
|
-
createDebug.debug = createDebug;
|
|
701
|
-
createDebug.default = createDebug;
|
|
702
|
-
createDebug.coerce = coerce;
|
|
703
|
-
createDebug.disable = disable;
|
|
704
|
-
createDebug.enable = enable;
|
|
705
|
-
createDebug.enabled = enabled;
|
|
706
|
-
createDebug.humanize = requireMs();
|
|
707
|
-
createDebug.destroy = destroy;
|
|
708
|
-
Object.keys(env).forEach((key) => {
|
|
709
|
-
createDebug[key] = env[key];
|
|
710
|
-
});
|
|
711
|
-
createDebug.names = [];
|
|
712
|
-
createDebug.skips = [];
|
|
713
|
-
createDebug.formatters = {};
|
|
714
|
-
function selectColor(namespace) {
|
|
715
|
-
let hash = 0;
|
|
716
|
-
for (let i = 0; i < namespace.length; i++) {
|
|
717
|
-
hash = (hash << 5) - hash + namespace.charCodeAt(i);
|
|
718
|
-
hash |= 0;
|
|
719
|
-
}
|
|
720
|
-
return createDebug.colors[Math.abs(hash) % createDebug.colors.length];
|
|
721
|
-
}
|
|
722
|
-
createDebug.selectColor = selectColor;
|
|
723
|
-
function createDebug(namespace) {
|
|
724
|
-
let prevTime;
|
|
725
|
-
let enableOverride = null;
|
|
726
|
-
let namespacesCache;
|
|
727
|
-
let enabledCache;
|
|
728
|
-
function debug2(...args) {
|
|
729
|
-
if (!debug2.enabled) {
|
|
730
|
-
return;
|
|
731
|
-
}
|
|
732
|
-
const self = debug2;
|
|
733
|
-
const curr = Number(/* @__PURE__ */ new Date());
|
|
734
|
-
const ms2 = curr - (prevTime || curr);
|
|
735
|
-
self.diff = ms2;
|
|
736
|
-
self.prev = prevTime;
|
|
737
|
-
self.curr = curr;
|
|
738
|
-
prevTime = curr;
|
|
739
|
-
args[0] = createDebug.coerce(args[0]);
|
|
740
|
-
if (typeof args[0] !== "string") {
|
|
741
|
-
args.unshift("%O");
|
|
742
|
-
}
|
|
743
|
-
let index = 0;
|
|
744
|
-
args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => {
|
|
745
|
-
if (match === "%%") {
|
|
746
|
-
return "%";
|
|
747
|
-
}
|
|
748
|
-
index++;
|
|
749
|
-
const formatter = createDebug.formatters[format];
|
|
750
|
-
if (typeof formatter === "function") {
|
|
751
|
-
const val = args[index];
|
|
752
|
-
match = formatter.call(self, val);
|
|
753
|
-
args.splice(index, 1);
|
|
754
|
-
index--;
|
|
755
|
-
}
|
|
756
|
-
return match;
|
|
757
|
-
});
|
|
758
|
-
createDebug.formatArgs.call(self, args);
|
|
759
|
-
const logFn = self.log || createDebug.log;
|
|
760
|
-
logFn.apply(self, args);
|
|
761
|
-
}
|
|
762
|
-
debug2.namespace = namespace;
|
|
763
|
-
debug2.useColors = createDebug.useColors();
|
|
764
|
-
debug2.color = createDebug.selectColor(namespace);
|
|
765
|
-
debug2.extend = extend;
|
|
766
|
-
debug2.destroy = createDebug.destroy;
|
|
767
|
-
Object.defineProperty(debug2, "enabled", {
|
|
768
|
-
enumerable: true,
|
|
769
|
-
configurable: false,
|
|
770
|
-
get: () => {
|
|
771
|
-
if (enableOverride !== null) {
|
|
772
|
-
return enableOverride;
|
|
773
|
-
}
|
|
774
|
-
if (namespacesCache !== createDebug.namespaces) {
|
|
775
|
-
namespacesCache = createDebug.namespaces;
|
|
776
|
-
enabledCache = createDebug.enabled(namespace);
|
|
777
|
-
}
|
|
778
|
-
return enabledCache;
|
|
779
|
-
},
|
|
780
|
-
set: (v) => {
|
|
781
|
-
enableOverride = v;
|
|
782
|
-
}
|
|
783
|
-
});
|
|
784
|
-
if (typeof createDebug.init === "function") {
|
|
785
|
-
createDebug.init(debug2);
|
|
786
|
-
}
|
|
787
|
-
return debug2;
|
|
788
|
-
}
|
|
789
|
-
function extend(namespace, delimiter) {
|
|
790
|
-
const newDebug = createDebug(this.namespace + (typeof delimiter === "undefined" ? ":" : delimiter) + namespace);
|
|
791
|
-
newDebug.log = this.log;
|
|
792
|
-
return newDebug;
|
|
793
|
-
}
|
|
794
|
-
function enable(namespaces) {
|
|
795
|
-
createDebug.save(namespaces);
|
|
796
|
-
createDebug.namespaces = namespaces;
|
|
797
|
-
createDebug.names = [];
|
|
798
|
-
createDebug.skips = [];
|
|
799
|
-
const split = (typeof namespaces === "string" ? namespaces : "").trim().replace(/\s+/g, ",").split(",").filter(Boolean);
|
|
800
|
-
for (const ns of split) {
|
|
801
|
-
if (ns[0] === "-") {
|
|
802
|
-
createDebug.skips.push(ns.slice(1));
|
|
803
|
-
} else {
|
|
804
|
-
createDebug.names.push(ns);
|
|
805
|
-
}
|
|
806
|
-
}
|
|
807
|
-
}
|
|
808
|
-
function matchesTemplate(search, template2) {
|
|
809
|
-
let searchIndex = 0;
|
|
810
|
-
let templateIndex = 0;
|
|
811
|
-
let starIndex = -1;
|
|
812
|
-
let matchIndex = 0;
|
|
813
|
-
while (searchIndex < search.length) {
|
|
814
|
-
if (templateIndex < template2.length && (template2[templateIndex] === search[searchIndex] || template2[templateIndex] === "*")) {
|
|
815
|
-
if (template2[templateIndex] === "*") {
|
|
816
|
-
starIndex = templateIndex;
|
|
817
|
-
matchIndex = searchIndex;
|
|
818
|
-
templateIndex++;
|
|
819
|
-
} else {
|
|
820
|
-
searchIndex++;
|
|
821
|
-
templateIndex++;
|
|
822
|
-
}
|
|
823
|
-
} else if (starIndex !== -1) {
|
|
824
|
-
templateIndex = starIndex + 1;
|
|
825
|
-
matchIndex++;
|
|
826
|
-
searchIndex = matchIndex;
|
|
827
|
-
} else {
|
|
828
|
-
return false;
|
|
829
|
-
}
|
|
830
|
-
}
|
|
831
|
-
while (templateIndex < template2.length && template2[templateIndex] === "*") {
|
|
832
|
-
templateIndex++;
|
|
833
|
-
}
|
|
834
|
-
return templateIndex === template2.length;
|
|
835
|
-
}
|
|
836
|
-
function disable() {
|
|
837
|
-
const namespaces = [
|
|
838
|
-
...createDebug.names,
|
|
839
|
-
...createDebug.skips.map((namespace) => "-" + namespace)
|
|
840
|
-
].join(",");
|
|
841
|
-
createDebug.enable("");
|
|
842
|
-
return namespaces;
|
|
843
|
-
}
|
|
844
|
-
function enabled(name) {
|
|
845
|
-
for (const skip of createDebug.skips) {
|
|
846
|
-
if (matchesTemplate(name, skip)) {
|
|
847
|
-
return false;
|
|
848
|
-
}
|
|
849
|
-
}
|
|
850
|
-
for (const ns of createDebug.names) {
|
|
851
|
-
if (matchesTemplate(name, ns)) {
|
|
852
|
-
return true;
|
|
853
|
-
}
|
|
854
|
-
}
|
|
855
|
-
return false;
|
|
856
|
-
}
|
|
857
|
-
function coerce(val) {
|
|
858
|
-
if (val instanceof Error) {
|
|
859
|
-
return val.stack || val.message;
|
|
860
|
-
}
|
|
861
|
-
return val;
|
|
862
|
-
}
|
|
863
|
-
function destroy() {
|
|
864
|
-
console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.");
|
|
865
|
-
}
|
|
866
|
-
createDebug.enable(createDebug.load());
|
|
867
|
-
return createDebug;
|
|
868
|
-
}
|
|
869
|
-
common = setup;
|
|
870
|
-
return common;
|
|
871
|
-
}
|
|
872
|
-
var hasRequiredBrowser;
|
|
873
|
-
function requireBrowser() {
|
|
874
|
-
if (hasRequiredBrowser) return browser.exports;
|
|
875
|
-
hasRequiredBrowser = 1;
|
|
876
|
-
(function(module, exports) {
|
|
877
|
-
var define_process_env_default = {};
|
|
878
|
-
exports.formatArgs = formatArgs;
|
|
879
|
-
exports.save = save;
|
|
880
|
-
exports.load = load;
|
|
881
|
-
exports.useColors = useColors;
|
|
882
|
-
exports.storage = localstorage();
|
|
883
|
-
exports.destroy = /* @__PURE__ */ (() => {
|
|
884
|
-
let warned = false;
|
|
885
|
-
return () => {
|
|
886
|
-
if (!warned) {
|
|
887
|
-
warned = true;
|
|
888
|
-
console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.");
|
|
889
|
-
}
|
|
890
|
-
};
|
|
891
|
-
})();
|
|
892
|
-
exports.colors = [
|
|
893
|
-
"#0000CC",
|
|
894
|
-
"#0000FF",
|
|
895
|
-
"#0033CC",
|
|
896
|
-
"#0033FF",
|
|
897
|
-
"#0066CC",
|
|
898
|
-
"#0066FF",
|
|
899
|
-
"#0099CC",
|
|
900
|
-
"#0099FF",
|
|
901
|
-
"#00CC00",
|
|
902
|
-
"#00CC33",
|
|
903
|
-
"#00CC66",
|
|
904
|
-
"#00CC99",
|
|
905
|
-
"#00CCCC",
|
|
906
|
-
"#00CCFF",
|
|
907
|
-
"#3300CC",
|
|
908
|
-
"#3300FF",
|
|
909
|
-
"#3333CC",
|
|
910
|
-
"#3333FF",
|
|
911
|
-
"#3366CC",
|
|
912
|
-
"#3366FF",
|
|
913
|
-
"#3399CC",
|
|
914
|
-
"#3399FF",
|
|
915
|
-
"#33CC00",
|
|
916
|
-
"#33CC33",
|
|
917
|
-
"#33CC66",
|
|
918
|
-
"#33CC99",
|
|
919
|
-
"#33CCCC",
|
|
920
|
-
"#33CCFF",
|
|
921
|
-
"#6600CC",
|
|
922
|
-
"#6600FF",
|
|
923
|
-
"#6633CC",
|
|
924
|
-
"#6633FF",
|
|
925
|
-
"#66CC00",
|
|
926
|
-
"#66CC33",
|
|
927
|
-
"#9900CC",
|
|
928
|
-
"#9900FF",
|
|
929
|
-
"#9933CC",
|
|
930
|
-
"#9933FF",
|
|
931
|
-
"#99CC00",
|
|
932
|
-
"#99CC33",
|
|
933
|
-
"#CC0000",
|
|
934
|
-
"#CC0033",
|
|
935
|
-
"#CC0066",
|
|
936
|
-
"#CC0099",
|
|
937
|
-
"#CC00CC",
|
|
938
|
-
"#CC00FF",
|
|
939
|
-
"#CC3300",
|
|
940
|
-
"#CC3333",
|
|
941
|
-
"#CC3366",
|
|
942
|
-
"#CC3399",
|
|
943
|
-
"#CC33CC",
|
|
944
|
-
"#CC33FF",
|
|
945
|
-
"#CC6600",
|
|
946
|
-
"#CC6633",
|
|
947
|
-
"#CC9900",
|
|
948
|
-
"#CC9933",
|
|
949
|
-
"#CCCC00",
|
|
950
|
-
"#CCCC33",
|
|
951
|
-
"#FF0000",
|
|
952
|
-
"#FF0033",
|
|
953
|
-
"#FF0066",
|
|
954
|
-
"#FF0099",
|
|
955
|
-
"#FF00CC",
|
|
956
|
-
"#FF00FF",
|
|
957
|
-
"#FF3300",
|
|
958
|
-
"#FF3333",
|
|
959
|
-
"#FF3366",
|
|
960
|
-
"#FF3399",
|
|
961
|
-
"#FF33CC",
|
|
962
|
-
"#FF33FF",
|
|
963
|
-
"#FF6600",
|
|
964
|
-
"#FF6633",
|
|
965
|
-
"#FF9900",
|
|
966
|
-
"#FF9933",
|
|
967
|
-
"#FFCC00",
|
|
968
|
-
"#FFCC33"
|
|
969
|
-
];
|
|
970
|
-
function useColors() {
|
|
971
|
-
if (typeof window !== "undefined" && window.process && (window.process.type === "renderer" || window.process.__nwjs)) {
|
|
972
|
-
return true;
|
|
973
|
-
}
|
|
974
|
-
if (typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
|
|
975
|
-
return false;
|
|
976
|
-
}
|
|
977
|
-
let m;
|
|
978
|
-
return typeof document !== "undefined" && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // Is firebug? http://stackoverflow.com/a/398120/376773
|
|
979
|
-
typeof window !== "undefined" && window.console && (window.console.firebug || window.console.exception && window.console.table) || // Is firefox >= v31?
|
|
980
|
-
// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
|
|
981
|
-
typeof navigator !== "undefined" && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)) && parseInt(m[1], 10) >= 31 || // Double check webkit in userAgent just in case we are in a worker
|
|
982
|
-
typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/);
|
|
983
|
-
}
|
|
984
|
-
function formatArgs(args) {
|
|
985
|
-
args[0] = (this.useColors ? "%c" : "") + this.namespace + (this.useColors ? " %c" : " ") + args[0] + (this.useColors ? "%c " : " ") + "+" + module.exports.humanize(this.diff);
|
|
986
|
-
if (!this.useColors) {
|
|
987
|
-
return;
|
|
988
|
-
}
|
|
989
|
-
const c = "color: " + this.color;
|
|
990
|
-
args.splice(1, 0, c, "color: inherit");
|
|
991
|
-
let index = 0;
|
|
992
|
-
let lastC = 0;
|
|
993
|
-
args[0].replace(/%[a-zA-Z%]/g, (match) => {
|
|
994
|
-
if (match === "%%") {
|
|
995
|
-
return;
|
|
996
|
-
}
|
|
997
|
-
index++;
|
|
998
|
-
if (match === "%c") {
|
|
999
|
-
lastC = index;
|
|
1000
|
-
}
|
|
1001
|
-
});
|
|
1002
|
-
args.splice(lastC, 0, c);
|
|
1003
|
-
}
|
|
1004
|
-
exports.log = console.debug || console.log || (() => {
|
|
1005
|
-
});
|
|
1006
|
-
function save(namespaces) {
|
|
1007
|
-
try {
|
|
1008
|
-
if (namespaces) {
|
|
1009
|
-
exports.storage.setItem("debug", namespaces);
|
|
1010
|
-
} else {
|
|
1011
|
-
exports.storage.removeItem("debug");
|
|
1012
|
-
}
|
|
1013
|
-
} catch (error) {
|
|
1014
|
-
}
|
|
1015
|
-
}
|
|
1016
|
-
function load() {
|
|
1017
|
-
let r;
|
|
1018
|
-
try {
|
|
1019
|
-
r = exports.storage.getItem("debug") || exports.storage.getItem("DEBUG");
|
|
1020
|
-
} catch (error) {
|
|
1021
|
-
}
|
|
1022
|
-
if (!r && typeof process !== "undefined" && "env" in process) {
|
|
1023
|
-
r = define_process_env_default.DEBUG;
|
|
1024
|
-
}
|
|
1025
|
-
return r;
|
|
1026
|
-
}
|
|
1027
|
-
function localstorage() {
|
|
1028
|
-
try {
|
|
1029
|
-
return localStorage;
|
|
1030
|
-
} catch (error) {
|
|
1031
|
-
}
|
|
1032
|
-
}
|
|
1033
|
-
module.exports = requireCommon()(exports);
|
|
1034
|
-
const { formatters } = module.exports;
|
|
1035
|
-
formatters.j = function(v) {
|
|
1036
|
-
try {
|
|
1037
|
-
return JSON.stringify(v);
|
|
1038
|
-
} catch (error) {
|
|
1039
|
-
return "[UnexpectedJSONParseError]: " + error.message;
|
|
1040
|
-
}
|
|
1041
|
-
};
|
|
1042
|
-
})(browser, browser.exports);
|
|
1043
|
-
return browser.exports;
|
|
1044
|
-
}
|
|
1045
|
-
var browserExports = requireBrowser();
|
|
1046
|
-
const debug = /* @__PURE__ */ getDefaultExportFromCjs(browserExports);
|
|
1047
|
-
debug("cabbages");
|
|
1048
|
-
const RepoContext = createContext(
|
|
1049
|
-
null
|
|
1050
|
-
);
|
|
1051
|
-
function createDocSignal(handle) {
|
|
1052
|
-
const [signal, setSignal] = createSignal(handle()?.doc());
|
|
1053
|
-
createEffect(() => {
|
|
1054
|
-
const h = handle();
|
|
1055
|
-
function update() {
|
|
1056
|
-
setSignal(() => h?.doc());
|
|
1057
|
-
}
|
|
1058
|
-
update();
|
|
1059
|
-
if (h) {
|
|
1060
|
-
h.on("change", update);
|
|
1061
|
-
onCleanup(() => h.off("change", update));
|
|
1062
|
-
}
|
|
1063
|
-
});
|
|
1064
|
-
return signal;
|
|
1065
|
-
}
|
|
1066
|
-
function resolveElement(source) {
|
|
1067
|
-
return typeof source === "function" ? source() : source;
|
|
1068
|
-
}
|
|
1069
|
-
function subscribe(element, selector, initialValue) {
|
|
1070
|
-
const [value, setValue] = createSignal(initialValue);
|
|
1071
|
-
onMount(() => {
|
|
1072
|
-
const target = resolveElement(element);
|
|
1073
|
-
if (!target)
|
|
1074
|
-
return;
|
|
1075
|
-
const unsubscribe = subscribe$1(target, selector, setValue);
|
|
1076
|
-
onCleanup(unsubscribe);
|
|
1077
|
-
});
|
|
1078
|
-
return value;
|
|
1079
|
-
}
|
|
1080
|
-
function subscribeDoc(element, selector) {
|
|
1081
|
-
const [handle, setHandle] = createSignal(void 0);
|
|
1082
|
-
onMount(() => {
|
|
1083
|
-
const target = resolveElement(element);
|
|
1084
|
-
if (!target)
|
|
1085
|
-
return;
|
|
1086
|
-
let canceled = false;
|
|
1087
|
-
const unsubscribe = subscribe$1(target, selector, (url) => {
|
|
1088
|
-
if (!url)
|
|
1089
|
-
return;
|
|
1090
|
-
const repo = "repo" in window ? window.repo : void 0;
|
|
1091
|
-
if (!repo)
|
|
1092
|
-
return;
|
|
1093
|
-
void Promise.resolve(repo.find(url)).then((h) => {
|
|
1094
|
-
if (canceled)
|
|
1095
|
-
return;
|
|
1096
|
-
setHandle(() => h);
|
|
1097
|
-
});
|
|
1098
|
-
});
|
|
1099
|
-
onCleanup(() => {
|
|
1100
|
-
canceled = true;
|
|
1101
|
-
unsubscribe();
|
|
1102
|
-
});
|
|
1103
|
-
});
|
|
1104
|
-
const [store, setStore] = createStore({});
|
|
1105
|
-
const [ready, setReady] = createSignal(false);
|
|
1106
|
-
createEffect(() => {
|
|
1107
|
-
const h = handle();
|
|
1108
|
-
if (!h) {
|
|
1109
|
-
setReady(false);
|
|
1110
|
-
return;
|
|
1111
|
-
}
|
|
1112
|
-
const sync = () => {
|
|
1113
|
-
setStore(reconcile(h.doc() ?? {}));
|
|
1114
|
-
setReady(true);
|
|
1115
|
-
};
|
|
1116
|
-
sync();
|
|
1117
|
-
h.on("change", sync);
|
|
1118
|
-
onCleanup(() => h.off("change", sync));
|
|
1119
|
-
});
|
|
1120
|
-
const doc = () => ready() ? store : void 0;
|
|
1121
|
-
return [doc, handle];
|
|
1122
|
-
}
|
|
1123
|
-
var _tmpl$ = /* @__PURE__ */ template(`<span class=drafts-hint>Drafts aren't supported for folders yet.`), _tmpl$2 = /* @__PURE__ */ template(`<div class="drafts-actions drafts-actions--top"><button class="drafts-btn drafts-btn--primary">New draft`), _tmpl$3 = /* @__PURE__ */ template(`<div class=drafts-list>`), _tmpl$4 = /* @__PURE__ */ template(`<div class=drafts-dropzone>Drop to fork a new draft from this version`), _tmpl$5 = /* @__PURE__ */ template(`<button class="drafts-btn drafts-btn--warning"title="Merge this draft into Main">Merge into Main`), _tmpl$6 = /* @__PURE__ */ template(`<div class=drafts-actions>`), _tmpl$7 = /* @__PURE__ */ template(`<div class=drafts-panel><div class=drafts-version>v0.0.18`), _tmpl$8 = /* @__PURE__ */ template(`<div class=drafts-empty>No document selected.`), _tmpl$9 = /* @__PURE__ */ template(`<span class=draft-badge>current`), _tmpl$0 = /* @__PURE__ */ template(`<div class=draft-card><div class=draft-card-header title="Main version (host document)"><div class=draft-card-title>`), _tmpl$1 = /* @__PURE__ */ template(`<div class=draft-card><div class=draft-card-header title="Open draft"><div class=draft-card-title>`), _tmpl$10 = /* @__PURE__ */ template(`<button type=button class=draft-card-return title="Return to the latest version">Return to latest`), _tmpl$11 = /* @__PURE__ */ template(`<input class=draft-name-input>`), _tmpl$12 = /* @__PURE__ */ template(`<span class=draft-name title="Double-click to rename">`), _tmpl$13 = /* @__PURE__ */ template(`<div class=draft-scrubber-token><div class=draft-scrubber-line></div><div class=draft-scrubber-edge title="Drag to scrub through history"></div><div class=draft-scrubber-dot title="Drag to scrub through history">`), _tmpl$14 = /* @__PURE__ */ template(`<div class=draft-changes-body><div class=draft-scrubber></div><div class=draft-changes-rows>`), _tmpl$15 = /* @__PURE__ */ template(`<div class=draft-card-changes>`), _tmpl$16 = /* @__PURE__ */ template(`<div class=draft-changes-empty>No changes yet.`), _tmpl$17 = /* @__PURE__ */ template(`<div class=draft-scrubber-sticker title="Drag out to fork a new draft from this version"><span class=draft-sticker-time></span><span class=draft-sticker-title></span><span class=draft-sticker-spacer>`), _tmpl$18 = /* @__PURE__ */ template(`<button type=button class=draft-group-row title="View the draft as of this group — drag out to fork a draft from it"><span class=draft-group-time></span><span class=draft-group-spacer>`), _tmpl$19 = /* @__PURE__ */ template(`<div class="draft-avatar draft-avatar--extra">+`), _tmpl$20 = /* @__PURE__ */ template(`<div class=draft-avatars>`), _tmpl$21 = /* @__PURE__ */ template(`<div class=draft-avatar>`), _tmpl$22 = /* @__PURE__ */ template(`<span class="draft-count draft-count--add">+`), _tmpl$23 = /* @__PURE__ */ template(`<span class="draft-count draft-count--del">-`), _tmpl$24 = /* @__PURE__ */ template(`<span class=draft-counts>`);
|
|
1124
|
-
const EMPTY_DRAFT_LIST = {
|
|
1125
|
-
main: {
|
|
1126
|
-
url: "",
|
|
1127
|
-
members: [],
|
|
1128
|
-
childCount: 0,
|
|
1129
|
-
name: null
|
|
1130
|
-
},
|
|
1131
|
-
drafts: []
|
|
1132
|
-
};
|
|
1133
|
-
const DRAFTS_VERSION = "0.0.18";
|
|
1134
|
-
console.log(`[drafts] DraftsSidebar v${DRAFTS_VERSION} loaded`);
|
|
1135
|
-
const INACTIVITY_GAP = 60 * 1e3;
|
|
1136
|
-
function DraftsSidebar(props) {
|
|
1137
|
-
const [hostDoc, hostDocHandle] = subscribeDoc(props.element, {
|
|
1138
|
-
type: "draft:root-doc"
|
|
1139
|
-
});
|
|
1140
|
-
const [, checkedOutHandle] = subscribeDoc(props.element, {
|
|
1141
|
-
type: "draft:checked-out"
|
|
1142
|
-
});
|
|
1143
|
-
const checkedOut = createDocSignal(checkedOutHandle);
|
|
1144
|
-
const selected = createMemo(() => checkedOut()?.checkedOut ?? null);
|
|
1145
|
-
const [scrubber, setScrubber] = createSignal(null);
|
|
1146
|
-
const [dragVersion, setDragVersion] = createSignal(null);
|
|
1147
|
-
const [dropActive, setDropActive] = createSignal(false);
|
|
1148
|
-
const list = subscribe(props.element, {
|
|
1149
|
-
type: "draft:list"
|
|
1150
|
-
}, EMPTY_DRAFT_LIST);
|
|
1151
|
-
const isMainSelected = createMemo(() => selected() === null);
|
|
1152
|
-
const isFolder = createMemo(() => hostDoc()?.["@patchwork"]?.type === "folder");
|
|
1153
|
-
const selectDraft = (url) => {
|
|
1154
|
-
const handle = checkedOutHandle();
|
|
1155
|
-
if (!handle) return;
|
|
1156
|
-
setScrubber(null);
|
|
1157
|
-
handle.change((d) => {
|
|
1158
|
-
d.checkedOut = url;
|
|
1159
|
-
d.at = null;
|
|
1160
|
-
});
|
|
1161
|
-
};
|
|
1162
|
-
const getRepo = () => "repo" in window ? window.repo : void 0;
|
|
1163
|
-
let scrubSeq = 0;
|
|
1164
|
-
const onScrub = (draftUrl, members, scrub) => {
|
|
1165
|
-
const handle = checkedOutHandle();
|
|
1166
|
-
const repo = getRepo();
|
|
1167
|
-
if (!handle || !repo) return;
|
|
1168
|
-
setScrubber(scrub);
|
|
1169
|
-
const seq = ++scrubSeq;
|
|
1170
|
-
void (async () => {
|
|
1171
|
-
const checkpoint = await computeCheckpoint(repo, members, scrub.head);
|
|
1172
|
-
if (seq !== scrubSeq) return;
|
|
1173
|
-
handle.change((d) => {
|
|
1174
|
-
d.checkedOut = draftUrl;
|
|
1175
|
-
d.at = checkpoint;
|
|
1176
|
-
});
|
|
1177
|
-
})();
|
|
1178
|
-
};
|
|
1179
|
-
const clearCheckpoint = () => {
|
|
1180
|
-
const handle = checkedOutHandle();
|
|
1181
|
-
if (!handle) return;
|
|
1182
|
-
setScrubber(null);
|
|
1183
|
-
handle.change((d) => {
|
|
1184
|
-
d.at = null;
|
|
1185
|
-
});
|
|
1186
|
-
};
|
|
1187
|
-
const onCreateDraft = async () => {
|
|
1188
|
-
if (isFolder()) return;
|
|
1189
|
-
const docHandle = hostDocHandle();
|
|
1190
|
-
if (!docHandle) return;
|
|
1191
|
-
const repo = getRepo();
|
|
1192
|
-
if (!repo) {
|
|
1193
|
-
console.warn("[drafts] window.repo is not set");
|
|
1194
|
-
return;
|
|
1195
|
-
}
|
|
1196
|
-
const mainDraft = await ensureMainDraft(repo, docHandle);
|
|
1197
|
-
const draft = repo.create({
|
|
1198
|
-
"@patchwork": {
|
|
1199
|
-
type: "draft"
|
|
1200
|
-
},
|
|
1201
|
-
parent: mainDraft.url,
|
|
1202
|
-
drafts: [],
|
|
1203
|
-
clones: {}
|
|
1204
|
-
});
|
|
1205
|
-
mainDraft.change((d) => {
|
|
1206
|
-
d.drafts.push(draft.url);
|
|
1207
|
-
});
|
|
1208
|
-
selectDraft(draft.url);
|
|
1209
|
-
};
|
|
1210
|
-
const ensureMainDraft = async (repo, docHandle) => {
|
|
1211
|
-
const existingUrl = docHandle.doc()?.["@patchwork"]?.mainDraftUrl;
|
|
1212
|
-
if (existingUrl) return repo.find(existingUrl);
|
|
1213
|
-
const mainDraft = repo.create({
|
|
1214
|
-
"@patchwork": {
|
|
1215
|
-
type: "draft"
|
|
1216
|
-
},
|
|
1217
|
-
isMain: true,
|
|
1218
|
-
parent: docHandle.url,
|
|
1219
|
-
drafts: [],
|
|
1220
|
-
clones: {}
|
|
1221
|
-
});
|
|
1222
|
-
docHandle.change((d) => {
|
|
1223
|
-
d["@patchwork"].mainDraftUrl = mainDraft.url;
|
|
1224
|
-
});
|
|
1225
|
-
return mainDraft;
|
|
1226
|
-
};
|
|
1227
|
-
const onCreateDraftFromVersion = async (members, head) => {
|
|
1228
|
-
if (isFolder()) return;
|
|
1229
|
-
const docHandle = hostDocHandle();
|
|
1230
|
-
if (!docHandle) return;
|
|
1231
|
-
const repo = getRepo();
|
|
1232
|
-
if (!repo) {
|
|
1233
|
-
console.warn("[drafts] window.repo is not set");
|
|
1234
|
-
return;
|
|
1235
|
-
}
|
|
1236
|
-
const checkpoint = await computeCheckpoint(repo, members, head);
|
|
1237
|
-
const clones = {};
|
|
1238
|
-
for (const member of members) {
|
|
1239
|
-
const to = checkpoint[member.url]?.to;
|
|
1240
|
-
if (!to) continue;
|
|
1241
|
-
let handle = null;
|
|
1242
|
-
try {
|
|
1243
|
-
handle = await repo.find(member.cloneUrl ?? member.url);
|
|
1244
|
-
const clone = cloneAtVersion(repo, handle, to);
|
|
1245
|
-
clones[member.url] = {
|
|
1246
|
-
cloneUrl: clone.url,
|
|
1247
|
-
clonedAt: to
|
|
1248
|
-
};
|
|
1249
|
-
} catch (err) {
|
|
1250
|
-
reportForkFailure(handle ? collectForkDiagnostic(handle, member, to) : null, err);
|
|
1251
|
-
}
|
|
1252
|
-
}
|
|
1253
|
-
const mainDraft = await ensureMainDraft(repo, docHandle);
|
|
1254
|
-
const draft = repo.create({
|
|
1255
|
-
"@patchwork": {
|
|
1256
|
-
type: "draft"
|
|
1257
|
-
},
|
|
1258
|
-
parent: mainDraft.url,
|
|
1259
|
-
drafts: [],
|
|
1260
|
-
clones
|
|
1261
|
-
});
|
|
1262
|
-
mainDraft.change((d) => {
|
|
1263
|
-
d.drafts.push(draft.url);
|
|
1264
|
-
});
|
|
1265
|
-
selectDraft(draft.url);
|
|
1266
|
-
};
|
|
1267
|
-
const onRename = async (url, name) => {
|
|
1268
|
-
const repo = getRepo();
|
|
1269
|
-
if (!repo) return;
|
|
1270
|
-
let handle;
|
|
1271
|
-
if (url === null) {
|
|
1272
|
-
const docHandle = hostDocHandle();
|
|
1273
|
-
if (!docHandle) return;
|
|
1274
|
-
handle = await ensureMainDraft(repo, docHandle);
|
|
1275
|
-
} else {
|
|
1276
|
-
handle = await repo.find(url);
|
|
1277
|
-
}
|
|
1278
|
-
handle.change((d) => {
|
|
1279
|
-
if (name) d.name = name;
|
|
1280
|
-
else delete d.name;
|
|
1281
|
-
});
|
|
1282
|
-
};
|
|
1283
|
-
const onMergeDraft = async () => {
|
|
1284
|
-
const draftUrl = selected();
|
|
1285
|
-
if (!draftUrl) return;
|
|
1286
|
-
if (!window.confirm("Merge this draft into the main document?")) return;
|
|
1287
|
-
const repo = getRepo();
|
|
1288
|
-
if (!repo) {
|
|
1289
|
-
console.warn("[drafts] window.repo is not set");
|
|
1290
|
-
return;
|
|
1291
|
-
}
|
|
1292
|
-
const draftHandle = await repo.find(draftUrl);
|
|
1293
|
-
await mergeDraft(repo, draftHandle);
|
|
1294
|
-
selectDraft(null);
|
|
1295
|
-
};
|
|
1296
|
-
return (() => {
|
|
1297
|
-
var _el$ = _tmpl$7(), _el$9 = _el$.firstChild;
|
|
1298
|
-
insert(_el$, createComponent(Show, {
|
|
1299
|
-
get when() {
|
|
1300
|
-
return hostDoc();
|
|
1301
|
-
},
|
|
1302
|
-
get fallback() {
|
|
1303
|
-
return _tmpl$8();
|
|
1304
|
-
},
|
|
1305
|
-
get children() {
|
|
1306
|
-
return [createComponent(Show, {
|
|
1307
|
-
get when() {
|
|
1308
|
-
return isMainSelected();
|
|
1309
|
-
},
|
|
1310
|
-
get children() {
|
|
1311
|
-
var _el$2 = _tmpl$2(), _el$3 = _el$2.firstChild;
|
|
1312
|
-
_el$3.$$click = onCreateDraft;
|
|
1313
|
-
insert(_el$2, createComponent(Show, {
|
|
1314
|
-
get when() {
|
|
1315
|
-
return isFolder();
|
|
1316
|
-
},
|
|
1317
|
-
get children() {
|
|
1318
|
-
return _tmpl$();
|
|
1319
|
-
}
|
|
1320
|
-
}), null);
|
|
1321
|
-
effect((_p$) => {
|
|
1322
|
-
var _v$ = isFolder(), _v$2 = isFolder() ? "Drafts aren't supported for folders yet" : "Create a new draft off this document";
|
|
1323
|
-
_v$ !== _p$.e && (_el$3.disabled = _p$.e = _v$);
|
|
1324
|
-
_v$2 !== _p$.t && setAttribute(_el$3, "title", _p$.t = _v$2);
|
|
1325
|
-
return _p$;
|
|
1326
|
-
}, {
|
|
1327
|
-
e: void 0,
|
|
1328
|
-
t: void 0
|
|
1329
|
-
});
|
|
1330
|
-
return _el$2;
|
|
1331
|
-
}
|
|
1332
|
-
}), (() => {
|
|
1333
|
-
var _el$5 = _tmpl$3();
|
|
1334
|
-
insert(_el$5, createComponent(MainCard, {
|
|
1335
|
-
get hostDocUrl() {
|
|
1336
|
-
return hostDocHandle()?.url;
|
|
1337
|
-
},
|
|
1338
|
-
get isSelected() {
|
|
1339
|
-
return isMainSelected();
|
|
1340
|
-
},
|
|
1341
|
-
members: () => list().main.members,
|
|
1342
|
-
get name() {
|
|
1343
|
-
return list().main.name;
|
|
1344
|
-
},
|
|
1345
|
-
onRename: (name) => void onRename(null, name),
|
|
1346
|
-
onSelect: () => selectDraft(null),
|
|
1347
|
-
onScrub: (scrub) => onScrub(null, list().main.members, scrub),
|
|
1348
|
-
scrubber: () => isMainSelected() ? scrubber() : null,
|
|
1349
|
-
onDragVersion: (head) => setDragVersion(head ? {
|
|
1350
|
-
members: list().main.members,
|
|
1351
|
-
head
|
|
1352
|
-
} : null),
|
|
1353
|
-
get hasCheckpoint() {
|
|
1354
|
-
return memo(() => !!isMainSelected())() && !!checkedOut()?.at;
|
|
1355
|
-
},
|
|
1356
|
-
onReturnToLatest: clearCheckpoint
|
|
1357
|
-
}), null);
|
|
1358
|
-
insert(_el$5, createComponent(For, {
|
|
1359
|
-
get each() {
|
|
1360
|
-
return list().drafts;
|
|
1361
|
-
},
|
|
1362
|
-
children: (summary) => createComponent(DraftCard, {
|
|
1363
|
-
get url() {
|
|
1364
|
-
return summary.url;
|
|
1365
|
-
},
|
|
1366
|
-
get members() {
|
|
1367
|
-
return summary.members;
|
|
1368
|
-
},
|
|
1369
|
-
get mainDocUrl() {
|
|
1370
|
-
return hostDocHandle()?.url;
|
|
1371
|
-
},
|
|
1372
|
-
get isSelected() {
|
|
1373
|
-
return selected() === summary.url;
|
|
1374
|
-
},
|
|
1375
|
-
get name() {
|
|
1376
|
-
return summary.name;
|
|
1377
|
-
},
|
|
1378
|
-
onRename: (name) => void onRename(summary.url, name),
|
|
1379
|
-
onSelect: selectDraft,
|
|
1380
|
-
onScrub: (scrub) => onScrub(summary.url, summary.members, scrub),
|
|
1381
|
-
scrubber: () => selected() === summary.url ? scrubber() : null,
|
|
1382
|
-
onDragVersion: (head) => setDragVersion(head ? {
|
|
1383
|
-
members: summary.members,
|
|
1384
|
-
head
|
|
1385
|
-
} : null),
|
|
1386
|
-
get hasCheckpoint() {
|
|
1387
|
-
return memo(() => selected() === summary.url)() && !!checkedOut()?.at;
|
|
1388
|
-
},
|
|
1389
|
-
onReturnToLatest: clearCheckpoint
|
|
1390
|
-
})
|
|
1391
|
-
}), null);
|
|
1392
|
-
return _el$5;
|
|
1393
|
-
})(), (() => {
|
|
1394
|
-
var _el$6 = _tmpl$6();
|
|
1395
|
-
insert(_el$6, createComponent(Show, {
|
|
1396
|
-
get when() {
|
|
1397
|
-
return dragVersion();
|
|
1398
|
-
},
|
|
1399
|
-
get children() {
|
|
1400
|
-
var _el$7 = _tmpl$4();
|
|
1401
|
-
_el$7.addEventListener("drop", (e) => {
|
|
1402
|
-
e.preventDefault();
|
|
1403
|
-
const version = dragVersion();
|
|
1404
|
-
setDropActive(false);
|
|
1405
|
-
setDragVersion(null);
|
|
1406
|
-
if (version) {
|
|
1407
|
-
void onCreateDraftFromVersion(version.members, version.head);
|
|
1408
|
-
}
|
|
1409
|
-
});
|
|
1410
|
-
_el$7.addEventListener("dragleave", () => setDropActive(false));
|
|
1411
|
-
_el$7.addEventListener("dragover", (e) => {
|
|
1412
|
-
e.preventDefault();
|
|
1413
|
-
if (e.dataTransfer) e.dataTransfer.dropEffect = "copy";
|
|
1414
|
-
});
|
|
1415
|
-
_el$7.addEventListener("dragenter", (e) => {
|
|
1416
|
-
e.preventDefault();
|
|
1417
|
-
setDropActive(true);
|
|
1418
|
-
});
|
|
1419
|
-
effect(() => setAttribute(_el$7, "data-over", dropActive() ? "" : void 0));
|
|
1420
|
-
return _el$7;
|
|
1421
|
-
}
|
|
1422
|
-
}), null);
|
|
1423
|
-
insert(_el$6, createComponent(Show, {
|
|
1424
|
-
get when() {
|
|
1425
|
-
return !isMainSelected();
|
|
1426
|
-
},
|
|
1427
|
-
get children() {
|
|
1428
|
-
var _el$8 = _tmpl$5();
|
|
1429
|
-
_el$8.$$click = onMergeDraft;
|
|
1430
|
-
return _el$8;
|
|
1431
|
-
}
|
|
1432
|
-
}), null);
|
|
1433
|
-
return _el$6;
|
|
1434
|
-
})()];
|
|
1435
|
-
}
|
|
1436
|
-
}), _el$9);
|
|
1437
|
-
return _el$;
|
|
1438
|
-
})();
|
|
1439
|
-
}
|
|
1440
|
-
async function mergeDraft(repo, draftHandle) {
|
|
1441
|
-
const entries = Object.entries(draftHandle.doc()?.clones ?? {});
|
|
1442
|
-
for (const [originalUrl, entry] of entries) {
|
|
1443
|
-
if (entry.cloneUrl === originalUrl) continue;
|
|
1444
|
-
const [original, clone] = await Promise.all([repo.find(originalUrl), repo.find(entry.cloneUrl)]);
|
|
1445
|
-
original.merge(clone);
|
|
1446
|
-
const mergedAt = original.heads();
|
|
1447
|
-
draftHandle.change((d) => {
|
|
1448
|
-
const e = d.clones[originalUrl];
|
|
1449
|
-
if (e) e.mergedAt = mergedAt;
|
|
1450
|
-
});
|
|
1451
|
-
}
|
|
1452
|
-
draftHandle.change((d) => {
|
|
1453
|
-
d.mergedAt = Date.now();
|
|
1454
|
-
});
|
|
1455
|
-
}
|
|
1456
|
-
function cloneAtVersion(repo, handle, to) {
|
|
1457
|
-
const doc = handle.doc();
|
|
1458
|
-
const pinHeads = decodeHeads(to);
|
|
1459
|
-
const metas = Automerge.getChangesMetaSince(doc, []);
|
|
1460
|
-
const byHash = new Map(metas.map((m) => [m.hash, m]));
|
|
1461
|
-
const closure = /* @__PURE__ */ new Set();
|
|
1462
|
-
const stack = [...pinHeads];
|
|
1463
|
-
while (stack.length > 0) {
|
|
1464
|
-
const hash = stack.pop();
|
|
1465
|
-
if (closure.has(hash)) continue;
|
|
1466
|
-
const meta = byHash.get(hash);
|
|
1467
|
-
if (!meta) {
|
|
1468
|
-
throw new Error(`[drafts] change ${hash} is not in the doc's history metadata`);
|
|
1469
|
-
}
|
|
1470
|
-
closure.add(hash);
|
|
1471
|
-
stack.push(...meta.deps);
|
|
1472
|
-
}
|
|
1473
|
-
const bundle = Automerge.saveBundle(doc, [...closure]);
|
|
1474
|
-
const pinned = Automerge.loadIncremental(Automerge.init(), bundle);
|
|
1475
|
-
const gotHeads = [...Automerge.getHeads(pinned)].sort();
|
|
1476
|
-
const wantHeads = [...pinHeads].sort();
|
|
1477
|
-
if (JSON.stringify(gotHeads) !== JSON.stringify(wantHeads)) {
|
|
1478
|
-
throw new Error(`[drafts] version clone heads mismatch: wanted ${wantHeads}, got ${gotHeads}`);
|
|
1479
|
-
}
|
|
1480
|
-
const clone = repo.create();
|
|
1481
|
-
clone.update(() => pinned);
|
|
1482
|
-
return clone;
|
|
1483
|
-
}
|
|
1484
|
-
function collectForkDiagnostic(handle, member, to) {
|
|
1485
|
-
const diagnostic = {
|
|
1486
|
-
draftsVersion: DRAFTS_VERSION,
|
|
1487
|
-
memberUrl: member.url,
|
|
1488
|
-
sourceUrl: member.cloneUrl ?? member.url,
|
|
1489
|
-
memberClonedAt: member.clonedAt,
|
|
1490
|
-
to,
|
|
1491
|
-
toHex: [],
|
|
1492
|
-
currentHeads: null,
|
|
1493
|
-
hasHeads: null,
|
|
1494
|
-
missingDeps: null,
|
|
1495
|
-
stats: null,
|
|
1496
|
-
automerge: null,
|
|
1497
|
-
pinnedChanges: [],
|
|
1498
|
-
fragments: null,
|
|
1499
|
-
probeErrors: []
|
|
1500
|
-
};
|
|
1501
|
-
const probe = (name, run) => {
|
|
1502
|
-
try {
|
|
1503
|
-
run();
|
|
1504
|
-
} catch (err) {
|
|
1505
|
-
diagnostic.probeErrors.push(`${name}: ${String(err)}`);
|
|
1506
|
-
}
|
|
1507
|
-
};
|
|
1508
|
-
probe("decodeHeads", () => {
|
|
1509
|
-
diagnostic.toHex = decodeHeads(to);
|
|
1510
|
-
});
|
|
1511
|
-
const doc = handle.doc();
|
|
1512
|
-
probe("getHeads", () => {
|
|
1513
|
-
diagnostic.currentHeads = Automerge.getHeads(doc);
|
|
1514
|
-
});
|
|
1515
|
-
probe("hasHeads", () => {
|
|
1516
|
-
diagnostic.hasHeads = Automerge.hasHeads(doc, diagnostic.toHex);
|
|
1517
|
-
});
|
|
1518
|
-
probe("getMissingDeps", () => {
|
|
1519
|
-
diagnostic.missingDeps = Automerge.getMissingDeps(doc, diagnostic.toHex);
|
|
1520
|
-
});
|
|
1521
|
-
probe("stats", () => {
|
|
1522
|
-
const s = Automerge.stats(doc);
|
|
1523
|
-
diagnostic.stats = {
|
|
1524
|
-
numChanges: s.numChanges,
|
|
1525
|
-
numOps: s.numOps
|
|
1526
|
-
};
|
|
1527
|
-
});
|
|
1528
|
-
probe("releaseInfo", () => {
|
|
1529
|
-
const info = Automerge.releaseInfo();
|
|
1530
|
-
diagnostic.automerge = {
|
|
1531
|
-
jsGitHead: info.js.gitHead,
|
|
1532
|
-
wasmGitHead: info.wasm?.gitHead ?? null,
|
|
1533
|
-
wasmVersion: info.wasm?.cargoPackageVersion ?? null
|
|
1534
|
-
};
|
|
1535
|
-
});
|
|
1536
|
-
probe("pinnedChanges", () => {
|
|
1537
|
-
const topo = Automerge.topoHistoryTraversal(doc);
|
|
1538
|
-
const metas = Automerge.getChangesMetaSince(doc, []);
|
|
1539
|
-
const metaByHash = new Map(metas.map((m) => [m.hash, m]));
|
|
1540
|
-
diagnostic.pinnedChanges = diagnostic.toHex.map((hash) => {
|
|
1541
|
-
const meta = metaByHash.get(hash);
|
|
1542
|
-
const topoIndex = topo.indexOf(hash);
|
|
1543
|
-
return {
|
|
1544
|
-
hash,
|
|
1545
|
-
known: !!meta || topoIndex >= 0,
|
|
1546
|
-
topoIndex: topoIndex >= 0 ? topoIndex : null,
|
|
1547
|
-
time: meta?.time ?? null,
|
|
1548
|
-
actor: meta?.actor ?? null,
|
|
1549
|
-
seq: meta?.seq ?? null,
|
|
1550
|
-
deps: meta?.deps ?? null,
|
|
1551
|
-
isCurrentHead: diagnostic.currentHeads?.includes(hash) ?? false
|
|
1552
|
-
};
|
|
1553
|
-
});
|
|
1554
|
-
});
|
|
1555
|
-
probe("fragments", () => {
|
|
1556
|
-
const topo = Automerge.topoHistoryTraversal(doc);
|
|
1557
|
-
const topoIndex = new Map(topo.map((h, i) => [h, i]));
|
|
1558
|
-
const pinned = new Set(diagnostic.toHex);
|
|
1559
|
-
diagnostic.fragments = Automerge.getFragmentMetadata(doc).map((f) => {
|
|
1560
|
-
let min = Infinity;
|
|
1561
|
-
let max = -Infinity;
|
|
1562
|
-
let containsPin = false;
|
|
1563
|
-
for (const h of f.members) {
|
|
1564
|
-
const i = topoIndex.get(h);
|
|
1565
|
-
if (i !== void 0) {
|
|
1566
|
-
if (i < min) min = i;
|
|
1567
|
-
if (i > max) max = i;
|
|
1568
|
-
}
|
|
1569
|
-
if (pinned.has(h)) containsPin = true;
|
|
1570
|
-
}
|
|
1571
|
-
return {
|
|
1572
|
-
level: f.level,
|
|
1573
|
-
head: f.head,
|
|
1574
|
-
memberCount: f.members.length,
|
|
1575
|
-
topoRange: min <= max ? [min, max] : null,
|
|
1576
|
-
containsPin
|
|
1577
|
-
};
|
|
1578
|
-
});
|
|
1579
|
-
});
|
|
1580
|
-
probe("saveDoc", () => {
|
|
1581
|
-
const bytes = Automerge.save(doc);
|
|
1582
|
-
let binary = "";
|
|
1583
|
-
const CHUNK = 32768;
|
|
1584
|
-
for (let i = 0; i < bytes.length; i += CHUNK) {
|
|
1585
|
-
binary += String.fromCharCode(...bytes.subarray(i, i + CHUNK));
|
|
1586
|
-
}
|
|
1587
|
-
lastForkRepro = {
|
|
1588
|
-
url: member.url,
|
|
1589
|
-
toHex: diagnostic.toHex,
|
|
1590
|
-
docBase64: btoa(binary)
|
|
1591
|
-
};
|
|
1592
|
-
});
|
|
1593
|
-
return diagnostic;
|
|
1594
|
-
}
|
|
1595
|
-
let lastForkRepro = null;
|
|
1596
|
-
function reportForkFailure(diagnostic, err) {
|
|
1597
|
-
const failure = {
|
|
1598
|
-
message: err instanceof Error ? err.message : String(err),
|
|
1599
|
-
stack: err instanceof Error ? err.stack : void 0
|
|
1600
|
-
};
|
|
1601
|
-
if (!diagnostic) {
|
|
1602
|
-
console.error("[drafts][fork-diagnostic] failed before diagnostics could be gathered:", failure);
|
|
1603
|
-
return;
|
|
1604
|
-
}
|
|
1605
|
-
diagnostic.failure = failure;
|
|
1606
|
-
if (lastForkRepro && lastForkRepro.url === diagnostic.memberUrl) {
|
|
1607
|
-
window.__draftsForkRepro = lastForkRepro;
|
|
1608
|
-
}
|
|
1609
|
-
console.error("[drafts][fork-diagnostic] failed to fork member at version — paste this block back:\n" + JSON.stringify(diagnostic, null, 2) + "\n[drafts][fork-diagnostic] the failing doc's bytes are on window.__draftsForkRepro — to save them for an offline repro, run:\n const r = window.__draftsForkRepro;\n const bytes = Uint8Array.from(atob(r.docBase64), c => c.charCodeAt(0));\n const a = document.createElement('a');\n a.href = URL.createObjectURL(new Blob([bytes]));\n a.download = 'fork-repro.automerge'; a.click();\n console.log('pin heads:', r.toHex);");
|
|
1610
|
-
}
|
|
1611
|
-
function MainCard(props) {
|
|
1612
|
-
return (() => {
|
|
1613
|
-
var _el$1 = _tmpl$0(), _el$10 = _el$1.firstChild, _el$11 = _el$10.firstChild;
|
|
1614
|
-
addEventListener(_el$10, "click", props.onSelect, true);
|
|
1615
|
-
insert(_el$11, createComponent(DraftName, {
|
|
1616
|
-
get name() {
|
|
1617
|
-
return props.name;
|
|
1618
|
-
},
|
|
1619
|
-
fallback: "Main",
|
|
1620
|
-
get onRename() {
|
|
1621
|
-
return props.onRename;
|
|
1622
|
-
}
|
|
1623
|
-
}), null);
|
|
1624
|
-
insert(_el$11, createComponent(Show, {
|
|
1625
|
-
get when() {
|
|
1626
|
-
return props.isSelected;
|
|
1627
|
-
},
|
|
1628
|
-
get children() {
|
|
1629
|
-
return _tmpl$9();
|
|
1630
|
-
}
|
|
1631
|
-
}), null);
|
|
1632
|
-
insert(_el$1, createComponent(Show, {
|
|
1633
|
-
get when() {
|
|
1634
|
-
return props.isSelected;
|
|
1635
|
-
},
|
|
1636
|
-
get children() {
|
|
1637
|
-
return [createComponent(DraftChangesList, {
|
|
1638
|
-
get members() {
|
|
1639
|
-
return props.members;
|
|
1640
|
-
},
|
|
1641
|
-
get mainDocUrl() {
|
|
1642
|
-
return props.hostDocUrl;
|
|
1643
|
-
},
|
|
1644
|
-
get onScrub() {
|
|
1645
|
-
return props.onScrub;
|
|
1646
|
-
},
|
|
1647
|
-
get scrubber() {
|
|
1648
|
-
return props.scrubber;
|
|
1649
|
-
},
|
|
1650
|
-
get onDragVersion() {
|
|
1651
|
-
return props.onDragVersion;
|
|
1652
|
-
}
|
|
1653
|
-
}), createComponent(ReturnToLatestButton, {
|
|
1654
|
-
get visible() {
|
|
1655
|
-
return props.hasCheckpoint;
|
|
1656
|
-
},
|
|
1657
|
-
get onClick() {
|
|
1658
|
-
return props.onReturnToLatest;
|
|
1659
|
-
}
|
|
1660
|
-
})];
|
|
1661
|
-
}
|
|
1662
|
-
}), null);
|
|
1663
|
-
effect(() => setAttribute(_el$1, "data-selected", props.isSelected ? "" : void 0));
|
|
1664
|
-
return _el$1;
|
|
1665
|
-
})();
|
|
1666
|
-
}
|
|
1667
|
-
function DraftCard(props) {
|
|
1668
|
-
return (() => {
|
|
1669
|
-
var _el$13 = _tmpl$1(), _el$14 = _el$13.firstChild, _el$15 = _el$14.firstChild;
|
|
1670
|
-
_el$14.$$click = () => props.onSelect(props.url);
|
|
1671
|
-
insert(_el$15, createComponent(DraftName, {
|
|
1672
|
-
get name() {
|
|
1673
|
-
return props.name;
|
|
1674
|
-
},
|
|
1675
|
-
fallback: "Draft",
|
|
1676
|
-
get onRename() {
|
|
1677
|
-
return props.onRename;
|
|
1678
|
-
}
|
|
1679
|
-
}), null);
|
|
1680
|
-
insert(_el$15, createComponent(Show, {
|
|
1681
|
-
get when() {
|
|
1682
|
-
return props.isSelected;
|
|
1683
|
-
},
|
|
1684
|
-
get children() {
|
|
1685
|
-
return _tmpl$9();
|
|
1686
|
-
}
|
|
1687
|
-
}), null);
|
|
1688
|
-
insert(_el$13, createComponent(Show, {
|
|
1689
|
-
get when() {
|
|
1690
|
-
return props.isSelected;
|
|
1691
|
-
},
|
|
1692
|
-
get children() {
|
|
1693
|
-
return [createComponent(DraftChangesList, {
|
|
1694
|
-
members: () => props.members,
|
|
1695
|
-
get mainDocUrl() {
|
|
1696
|
-
return props.mainDocUrl;
|
|
1697
|
-
},
|
|
1698
|
-
get onScrub() {
|
|
1699
|
-
return props.onScrub;
|
|
1700
|
-
},
|
|
1701
|
-
get scrubber() {
|
|
1702
|
-
return props.scrubber;
|
|
1703
|
-
},
|
|
1704
|
-
get onDragVersion() {
|
|
1705
|
-
return props.onDragVersion;
|
|
1706
|
-
}
|
|
1707
|
-
}), createComponent(ReturnToLatestButton, {
|
|
1708
|
-
get visible() {
|
|
1709
|
-
return props.hasCheckpoint;
|
|
1710
|
-
},
|
|
1711
|
-
get onClick() {
|
|
1712
|
-
return props.onReturnToLatest;
|
|
1713
|
-
}
|
|
1714
|
-
})];
|
|
1715
|
-
}
|
|
1716
|
-
}), null);
|
|
1717
|
-
effect(() => setAttribute(_el$13, "data-selected", props.isSelected ? "" : void 0));
|
|
1718
|
-
return _el$13;
|
|
1719
|
-
})();
|
|
1720
|
-
}
|
|
1721
|
-
function ReturnToLatestButton(props) {
|
|
1722
|
-
return createComponent(Show, {
|
|
1723
|
-
get when() {
|
|
1724
|
-
return props.visible;
|
|
1725
|
-
},
|
|
1726
|
-
get children() {
|
|
1727
|
-
var _el$17 = _tmpl$10();
|
|
1728
|
-
addEventListener(_el$17, "click", props.onClick, true);
|
|
1729
|
-
return _el$17;
|
|
1730
|
-
}
|
|
1731
|
-
});
|
|
1732
|
-
}
|
|
1733
|
-
function DraftName(props) {
|
|
1734
|
-
const [editing, setEditing] = createSignal(false);
|
|
1735
|
-
return createComponent(Show, {
|
|
1736
|
-
get when() {
|
|
1737
|
-
return editing();
|
|
1738
|
-
},
|
|
1739
|
-
get fallback() {
|
|
1740
|
-
return (() => {
|
|
1741
|
-
var _el$19 = _tmpl$12();
|
|
1742
|
-
_el$19.$$dblclick = () => setEditing(true);
|
|
1743
|
-
insert(_el$19, () => props.name ?? props.fallback);
|
|
1744
|
-
return _el$19;
|
|
1745
|
-
})();
|
|
1746
|
-
},
|
|
1747
|
-
get children() {
|
|
1748
|
-
var _el$18 = _tmpl$11();
|
|
1749
|
-
_el$18.addEventListener("blur", (e) => {
|
|
1750
|
-
if (!editing()) return;
|
|
1751
|
-
setEditing(false);
|
|
1752
|
-
const value = e.currentTarget.value.trim();
|
|
1753
|
-
if (value !== (props.name ?? "")) props.onRename(value || null);
|
|
1754
|
-
});
|
|
1755
|
-
_el$18.$$keydown = (e) => {
|
|
1756
|
-
if (e.key === "Enter") e.currentTarget.blur();
|
|
1757
|
-
if (e.key === "Escape") setEditing(false);
|
|
1758
|
-
};
|
|
1759
|
-
_el$18.$$dblclick = (e) => e.stopPropagation();
|
|
1760
|
-
_el$18.$$click = (e) => e.stopPropagation();
|
|
1761
|
-
use((el) => setTimeout(() => el.select()), _el$18);
|
|
1762
|
-
effect(() => setAttribute(_el$18, "placeholder", props.fallback));
|
|
1763
|
-
effect(() => _el$18.value = props.name ?? "");
|
|
1764
|
-
return _el$18;
|
|
1765
|
-
}
|
|
1766
|
-
});
|
|
1767
|
-
}
|
|
1768
|
-
function changeRef(change) {
|
|
1769
|
-
return {
|
|
1770
|
-
docUrl: change.docUrl,
|
|
1771
|
-
hash: change.hash,
|
|
1772
|
-
time: change.time
|
|
1773
|
-
};
|
|
1774
|
-
}
|
|
1775
|
-
function DraftChangesList(props) {
|
|
1776
|
-
const [changes, setChanges] = createSignal([]);
|
|
1777
|
-
createEffect(() => {
|
|
1778
|
-
const list = props.members();
|
|
1779
|
-
const mainDocUrl = props.mainDocUrl;
|
|
1780
|
-
const repo = "repo" in window ? window.repo : void 0;
|
|
1781
|
-
if (!repo) return;
|
|
1782
|
-
let disposed = false;
|
|
1783
|
-
const listeners = [];
|
|
1784
|
-
const recompute = async () => {
|
|
1785
|
-
const next = await collectInterleavedChanges(repo, list, mainDocUrl);
|
|
1786
|
-
if (!disposed) setChanges(next);
|
|
1787
|
-
};
|
|
1788
|
-
void (async () => {
|
|
1789
|
-
for (const member of list) {
|
|
1790
|
-
const handle = await repo.find(member.cloneUrl ?? member.url);
|
|
1791
|
-
if (disposed) return;
|
|
1792
|
-
const onChange = () => void recompute();
|
|
1793
|
-
handle.on("change", onChange);
|
|
1794
|
-
listeners.push({
|
|
1795
|
-
handle,
|
|
1796
|
-
onChange
|
|
1797
|
-
});
|
|
1798
|
-
}
|
|
1799
|
-
void recompute();
|
|
1800
|
-
})();
|
|
1801
|
-
onCleanup(() => {
|
|
1802
|
-
disposed = true;
|
|
1803
|
-
for (const {
|
|
1804
|
-
handle,
|
|
1805
|
-
onChange
|
|
1806
|
-
} of listeners) {
|
|
1807
|
-
handle.off("change", onChange);
|
|
1808
|
-
}
|
|
1809
|
-
});
|
|
1810
|
-
});
|
|
1811
|
-
const timeGroups = createMemo(() => groupChanges(changes()).filter((g) => g.additions > 0 || g.deletions > 0));
|
|
1812
|
-
const visibleChanges = createMemo(() => timeGroups().flatMap((g) => g.changes));
|
|
1813
|
-
const scrubTo = (headIndex2) => {
|
|
1814
|
-
const head = visibleChanges()[headIndex2];
|
|
1815
|
-
if (!head) return;
|
|
1816
|
-
props.onScrub({
|
|
1817
|
-
head: changeRef(head)
|
|
1818
|
-
});
|
|
1819
|
-
};
|
|
1820
|
-
const scrubToGroup = (group) => {
|
|
1821
|
-
props.onScrub({
|
|
1822
|
-
head: changeRef(group.newest)
|
|
1823
|
-
});
|
|
1824
|
-
};
|
|
1825
|
-
const headIndex = createMemo(() => {
|
|
1826
|
-
const s = props.scrubber();
|
|
1827
|
-
if (!s) return null;
|
|
1828
|
-
const idx = visibleChanges().findIndex((c) => c.hash === s.head.hash && c.docUrl === s.head.docUrl);
|
|
1829
|
-
return idx >= 0 ? idx : null;
|
|
1830
|
-
});
|
|
1831
|
-
const groupContainsHead = (group) => {
|
|
1832
|
-
const s = props.scrubber();
|
|
1833
|
-
return !!s && group.changes.some((c) => c.hash === s.head.hash && c.docUrl === s.head.docUrl);
|
|
1834
|
-
};
|
|
1835
|
-
const rowEls = /* @__PURE__ */ new Map();
|
|
1836
|
-
const [rowsEl, setRowsEl] = createSignal();
|
|
1837
|
-
const [measureTick, setMeasureTick] = createSignal(0);
|
|
1838
|
-
createEffect(() => {
|
|
1839
|
-
const el = rowsEl();
|
|
1840
|
-
if (!el) return;
|
|
1841
|
-
const observer = new ResizeObserver(() => setMeasureTick((t) => t + 1));
|
|
1842
|
-
observer.observe(el);
|
|
1843
|
-
onCleanup(() => observer.disconnect());
|
|
1844
|
-
});
|
|
1845
|
-
createEffect(() => {
|
|
1846
|
-
timeGroups();
|
|
1847
|
-
requestAnimationFrame(() => setMeasureTick((t) => t + 1));
|
|
1848
|
-
});
|
|
1849
|
-
const bands = createMemo(() => {
|
|
1850
|
-
measureTick();
|
|
1851
|
-
const out = [];
|
|
1852
|
-
let index = 0;
|
|
1853
|
-
for (const group of timeGroups()) {
|
|
1854
|
-
const el = rowEls.get(group.id);
|
|
1855
|
-
if (el) {
|
|
1856
|
-
out.push({
|
|
1857
|
-
startIndex: index,
|
|
1858
|
-
count: group.changes.length,
|
|
1859
|
-
top: el.offsetTop,
|
|
1860
|
-
height: el.offsetHeight
|
|
1861
|
-
});
|
|
1862
|
-
}
|
|
1863
|
-
index += group.changes.length;
|
|
1864
|
-
}
|
|
1865
|
-
return out;
|
|
1866
|
-
});
|
|
1867
|
-
const yForIndex = (index) => {
|
|
1868
|
-
const bs = bands();
|
|
1869
|
-
if (bs.length === 0) return 0;
|
|
1870
|
-
for (const b of bs) {
|
|
1871
|
-
if (index < b.startIndex + b.count) {
|
|
1872
|
-
return b.top + (index - b.startIndex) / b.count * b.height;
|
|
1873
|
-
}
|
|
1874
|
-
}
|
|
1875
|
-
const last = bs[bs.length - 1];
|
|
1876
|
-
return last.top + last.height;
|
|
1877
|
-
};
|
|
1878
|
-
const indexForY = (y) => {
|
|
1879
|
-
const bs = bands();
|
|
1880
|
-
if (bs.length === 0) return 0;
|
|
1881
|
-
for (const b of bs) {
|
|
1882
|
-
if (y < b.top) return b.startIndex;
|
|
1883
|
-
if (y < b.top + b.height) {
|
|
1884
|
-
const idx = b.startIndex + Math.round((y - b.top) / b.height * b.count);
|
|
1885
|
-
return Math.min(idx, b.startIndex + b.count - 1);
|
|
1886
|
-
}
|
|
1887
|
-
}
|
|
1888
|
-
const last = bs[bs.length - 1];
|
|
1889
|
-
return Math.max(0, last.startIndex + last.count - 1);
|
|
1890
|
-
};
|
|
1891
|
-
const tokenGeometry = createMemo(() => {
|
|
1892
|
-
if (visibleChanges().length === 0 || bands().length === 0) return null;
|
|
1893
|
-
return {
|
|
1894
|
-
top: yForIndex(headIndex() ?? 0)
|
|
1895
|
-
};
|
|
1896
|
-
});
|
|
1897
|
-
let trackEl;
|
|
1898
|
-
const yInTrack = (ev) => {
|
|
1899
|
-
const rect = trackEl.getBoundingClientRect();
|
|
1900
|
-
return ev.clientY - rect.top;
|
|
1901
|
-
};
|
|
1902
|
-
const beginDrag = (ev) => {
|
|
1903
|
-
if (!trackEl || visibleChanges().length === 0) return;
|
|
1904
|
-
ev.preventDefault();
|
|
1905
|
-
ev.stopPropagation();
|
|
1906
|
-
const grabOffset = yInTrack(ev) - yForIndex(headIndex() ?? 0);
|
|
1907
|
-
let last = headIndex() ?? 0;
|
|
1908
|
-
const onMove = (e) => {
|
|
1909
|
-
const head = indexForY(yInTrack(e) - grabOffset);
|
|
1910
|
-
if (head === last) return;
|
|
1911
|
-
last = head;
|
|
1912
|
-
scrubTo(head);
|
|
1913
|
-
};
|
|
1914
|
-
const target = ev.currentTarget;
|
|
1915
|
-
target.setPointerCapture(ev.pointerId);
|
|
1916
|
-
const onUp = () => {
|
|
1917
|
-
target.removeEventListener("pointermove", onMove);
|
|
1918
|
-
target.removeEventListener("pointerup", onUp);
|
|
1919
|
-
target.removeEventListener("pointercancel", onUp);
|
|
1920
|
-
};
|
|
1921
|
-
target.addEventListener("pointermove", onMove);
|
|
1922
|
-
target.addEventListener("pointerup", onUp);
|
|
1923
|
-
target.addEventListener("pointercancel", onUp);
|
|
1924
|
-
};
|
|
1925
|
-
const beginVersionDrag = (ev, head) => {
|
|
1926
|
-
if (!ev.dataTransfer) return;
|
|
1927
|
-
ev.dataTransfer.setData("text/plain", `${head.docUrl}#${head.hash}`);
|
|
1928
|
-
ev.dataTransfer.effectAllowed = "copy";
|
|
1929
|
-
props.onDragVersion(head);
|
|
1930
|
-
};
|
|
1931
|
-
const headChange = createMemo(() => {
|
|
1932
|
-
const idx = headIndex();
|
|
1933
|
-
const change = idx === null ? null : visibleChanges()[idx] ?? null;
|
|
1934
|
-
if (!change) return null;
|
|
1935
|
-
const atGroupStart = timeGroups().some((g) => g.newest.hash === change.hash && g.newest.docUrl === change.docUrl);
|
|
1936
|
-
return atGroupStart ? null : change;
|
|
1937
|
-
});
|
|
1938
|
-
return (() => {
|
|
1939
|
-
var _el$20 = _tmpl$15();
|
|
1940
|
-
insert(_el$20, createComponent(Show, {
|
|
1941
|
-
get when() {
|
|
1942
|
-
return timeGroups().length > 0;
|
|
1943
|
-
},
|
|
1944
|
-
get fallback() {
|
|
1945
|
-
return _tmpl$16();
|
|
1946
|
-
},
|
|
1947
|
-
get children() {
|
|
1948
|
-
var _el$21 = _tmpl$14(), _el$22 = _el$21.firstChild, _el$23 = _el$22.nextSibling;
|
|
1949
|
-
var _ref$ = trackEl;
|
|
1950
|
-
typeof _ref$ === "function" ? use(_ref$, _el$22) : trackEl = _el$22;
|
|
1951
|
-
use(setRowsEl, _el$23);
|
|
1952
|
-
insert(_el$23, createComponent(For, {
|
|
1953
|
-
get each() {
|
|
1954
|
-
return timeGroups();
|
|
1955
|
-
},
|
|
1956
|
-
children: (group) => createComponent(TimeGroupRow, {
|
|
1957
|
-
group,
|
|
1958
|
-
rowRef: (el) => rowEls.set(group.id, el),
|
|
1959
|
-
get isSelected() {
|
|
1960
|
-
return groupContainsHead(group);
|
|
1961
|
-
},
|
|
1962
|
-
onSelect: () => scrubToGroup(group),
|
|
1963
|
-
onVersionDragStart: (e) => beginVersionDrag(e, changeRef(group.newest)),
|
|
1964
|
-
onVersionDragEnd: () => props.onDragVersion(null)
|
|
1965
|
-
})
|
|
1966
|
-
}));
|
|
1967
|
-
insert(_el$21, createComponent(Show, {
|
|
1968
|
-
get when() {
|
|
1969
|
-
return tokenGeometry();
|
|
1970
|
-
},
|
|
1971
|
-
get children() {
|
|
1972
|
-
var _el$24 = _tmpl$13(), _el$25 = _el$24.firstChild, _el$26 = _el$25.nextSibling, _el$27 = _el$26.nextSibling;
|
|
1973
|
-
_el$26.$$pointerdown = beginDrag;
|
|
1974
|
-
_el$27.$$pointerdown = beginDrag;
|
|
1975
|
-
insert(_el$24, createComponent(Show, {
|
|
1976
|
-
get when() {
|
|
1977
|
-
return headChange();
|
|
1978
|
-
},
|
|
1979
|
-
children: (change) => (() => {
|
|
1980
|
-
var _el$29 = _tmpl$17(), _el$30 = _el$29.firstChild, _el$31 = _el$30.nextSibling;
|
|
1981
|
-
_el$31.nextSibling;
|
|
1982
|
-
_el$29.addEventListener("dragend", () => props.onDragVersion(null));
|
|
1983
|
-
_el$29.addEventListener("dragstart", (e) => beginVersionDrag(e, changeRef(change())));
|
|
1984
|
-
setAttribute(_el$29, "draggable", true);
|
|
1985
|
-
insert(_el$30, () => formatTime(change().time));
|
|
1986
|
-
insert(_el$31, () => change().title);
|
|
1987
|
-
insert(_el$29, createComponent(EditCounts, {
|
|
1988
|
-
get additions() {
|
|
1989
|
-
return change().additions;
|
|
1990
|
-
},
|
|
1991
|
-
get deletions() {
|
|
1992
|
-
return change().deletions;
|
|
1993
|
-
}
|
|
1994
|
-
}), null);
|
|
1995
|
-
return _el$29;
|
|
1996
|
-
})()
|
|
1997
|
-
}), null);
|
|
1998
|
-
effect((_p$) => {
|
|
1999
|
-
var _v$3 = headIndex() === null ? "" : void 0, _v$4 = `${tokenGeometry().top}px`;
|
|
2000
|
-
_v$3 !== _p$.e && setAttribute(_el$24, "data-live", _p$.e = _v$3);
|
|
2001
|
-
_v$4 !== _p$.t && setStyleProperty(_el$24, "top", _p$.t = _v$4);
|
|
2002
|
-
return _p$;
|
|
2003
|
-
}, {
|
|
2004
|
-
e: void 0,
|
|
2005
|
-
t: void 0
|
|
2006
|
-
});
|
|
2007
|
-
return _el$24;
|
|
2008
|
-
}
|
|
2009
|
-
}), null);
|
|
2010
|
-
return _el$21;
|
|
2011
|
-
}
|
|
2012
|
-
}));
|
|
2013
|
-
return _el$20;
|
|
2014
|
-
})();
|
|
2015
|
-
}
|
|
2016
|
-
function TimeGroupRow(props) {
|
|
2017
|
-
return (() => {
|
|
2018
|
-
var _el$33 = _tmpl$18(), _el$34 = _el$33.firstChild;
|
|
2019
|
-
_el$34.nextSibling;
|
|
2020
|
-
addEventListener(_el$33, "dragend", props.onVersionDragEnd);
|
|
2021
|
-
addEventListener(_el$33, "dragstart", props.onVersionDragStart);
|
|
2022
|
-
addEventListener(_el$33, "click", props.onSelect, true);
|
|
2023
|
-
var _ref$2 = props.rowRef;
|
|
2024
|
-
typeof _ref$2 === "function" ? use(_ref$2, _el$33) : props.rowRef = _el$33;
|
|
2025
|
-
setAttribute(_el$33, "draggable", true);
|
|
2026
|
-
insert(_el$33, createComponent(AuthorAvatars, {
|
|
2027
|
-
get actors() {
|
|
2028
|
-
return props.group.actors;
|
|
2029
|
-
}
|
|
2030
|
-
}), _el$34);
|
|
2031
|
-
insert(_el$34, () => formatTime(props.group.endTime));
|
|
2032
|
-
insert(_el$33, createComponent(EditCounts, {
|
|
2033
|
-
get additions() {
|
|
2034
|
-
return props.group.additions;
|
|
2035
|
-
},
|
|
2036
|
-
get deletions() {
|
|
2037
|
-
return props.group.deletions;
|
|
2038
|
-
}
|
|
2039
|
-
}), null);
|
|
2040
|
-
effect(() => setAttribute(_el$33, "data-selected", props.isSelected ? "" : void 0));
|
|
2041
|
-
return _el$33;
|
|
2042
|
-
})();
|
|
2043
|
-
}
|
|
2044
|
-
function AuthorAvatars(props) {
|
|
2045
|
-
const visible = () => props.actors.slice(0, 3);
|
|
2046
|
-
const extra = () => Math.max(0, props.actors.length - 3);
|
|
2047
|
-
return (() => {
|
|
2048
|
-
var _el$36 = _tmpl$20();
|
|
2049
|
-
insert(_el$36, createComponent(For, {
|
|
2050
|
-
get each() {
|
|
2051
|
-
return visible();
|
|
2052
|
-
},
|
|
2053
|
-
children: (actor, i) => (() => {
|
|
2054
|
-
var _el$39 = _tmpl$21();
|
|
2055
|
-
setAttribute(_el$39, "title", actor);
|
|
2056
|
-
insert(_el$39, () => getInitials(actor));
|
|
2057
|
-
effect((_p$) => {
|
|
2058
|
-
var _v$5 = authorColor(actor), _v$6 = i() === 0 ? "0" : "-4px", _v$7 = String(visible().length - i());
|
|
2059
|
-
_v$5 !== _p$.e && setStyleProperty(_el$39, "background", _p$.e = _v$5);
|
|
2060
|
-
_v$6 !== _p$.t && setStyleProperty(_el$39, "margin-left", _p$.t = _v$6);
|
|
2061
|
-
_v$7 !== _p$.a && setStyleProperty(_el$39, "z-index", _p$.a = _v$7);
|
|
2062
|
-
return _p$;
|
|
2063
|
-
}, {
|
|
2064
|
-
e: void 0,
|
|
2065
|
-
t: void 0,
|
|
2066
|
-
a: void 0
|
|
2067
|
-
});
|
|
2068
|
-
return _el$39;
|
|
2069
|
-
})()
|
|
2070
|
-
}), null);
|
|
2071
|
-
insert(_el$36, createComponent(Show, {
|
|
2072
|
-
get when() {
|
|
2073
|
-
return extra() > 0;
|
|
2074
|
-
},
|
|
2075
|
-
get children() {
|
|
2076
|
-
var _el$37 = _tmpl$19();
|
|
2077
|
-
_el$37.firstChild;
|
|
2078
|
-
insert(_el$37, extra, null);
|
|
2079
|
-
return _el$37;
|
|
2080
|
-
}
|
|
2081
|
-
}), null);
|
|
2082
|
-
return _el$36;
|
|
2083
|
-
})();
|
|
2084
|
-
}
|
|
2085
|
-
function EditCounts(props) {
|
|
2086
|
-
return (() => {
|
|
2087
|
-
var _el$40 = _tmpl$24();
|
|
2088
|
-
insert(_el$40, createComponent(Show, {
|
|
2089
|
-
get when() {
|
|
2090
|
-
return props.additions > 0;
|
|
2091
|
-
},
|
|
2092
|
-
get children() {
|
|
2093
|
-
var _el$41 = _tmpl$22();
|
|
2094
|
-
_el$41.firstChild;
|
|
2095
|
-
insert(_el$41, () => props.additions, null);
|
|
2096
|
-
return _el$41;
|
|
2097
|
-
}
|
|
2098
|
-
}), null);
|
|
2099
|
-
insert(_el$40, createComponent(Show, {
|
|
2100
|
-
get when() {
|
|
2101
|
-
return props.deletions > 0;
|
|
2102
|
-
},
|
|
2103
|
-
get children() {
|
|
2104
|
-
var _el$43 = _tmpl$23();
|
|
2105
|
-
_el$43.firstChild;
|
|
2106
|
-
insert(_el$43, () => props.deletions, null);
|
|
2107
|
-
return _el$43;
|
|
2108
|
-
}
|
|
2109
|
-
}), null);
|
|
2110
|
-
return _el$40;
|
|
2111
|
-
})();
|
|
2112
|
-
}
|
|
2113
|
-
function groupChanges(changes) {
|
|
2114
|
-
const timeGroups = [];
|
|
2115
|
-
let window2 = [];
|
|
2116
|
-
let prevTimeMs = null;
|
|
2117
|
-
const flush = () => {
|
|
2118
|
-
if (window2.length > 0) {
|
|
2119
|
-
timeGroups.push(buildTimeGroup(window2));
|
|
2120
|
-
window2 = [];
|
|
2121
|
-
}
|
|
2122
|
-
};
|
|
2123
|
-
for (const change of changes) {
|
|
2124
|
-
const timeMs = change.time * 1e3;
|
|
2125
|
-
if (prevTimeMs !== null && prevTimeMs - timeMs > INACTIVITY_GAP) flush();
|
|
2126
|
-
window2.push(change);
|
|
2127
|
-
prevTimeMs = timeMs;
|
|
2128
|
-
}
|
|
2129
|
-
flush();
|
|
2130
|
-
return timeGroups;
|
|
2131
|
-
}
|
|
2132
|
-
function buildTimeGroup(windowNewestFirst) {
|
|
2133
|
-
const actors = [];
|
|
2134
|
-
let additions = 0;
|
|
2135
|
-
let deletions = 0;
|
|
2136
|
-
for (const c of windowNewestFirst) {
|
|
2137
|
-
if (!actors.includes(c.actor)) actors.push(c.actor);
|
|
2138
|
-
additions += c.additions;
|
|
2139
|
-
deletions += c.deletions;
|
|
2140
|
-
}
|
|
2141
|
-
const newest = windowNewestFirst[0];
|
|
2142
|
-
return {
|
|
2143
|
-
id: `tg-${newest.hash}`,
|
|
2144
|
-
endTime: newest.time,
|
|
2145
|
-
actors,
|
|
2146
|
-
additions,
|
|
2147
|
-
deletions,
|
|
2148
|
-
newest,
|
|
2149
|
-
changes: windowNewestFirst
|
|
2150
|
-
};
|
|
2151
|
-
}
|
|
2152
|
-
async function computeCheckpoint(repo, members, head) {
|
|
2153
|
-
const checkpoint = {};
|
|
2154
|
-
for (const member of members) {
|
|
2155
|
-
try {
|
|
2156
|
-
const handle = await repo.find(member.cloneUrl ?? member.url);
|
|
2157
|
-
const doc = handle.doc();
|
|
2158
|
-
if (!doc) continue;
|
|
2159
|
-
const since = member.clonedAt ? decodeHeads(member.clonedAt) : [];
|
|
2160
|
-
const metas = Automerge.getChangesMetaSince(doc, since);
|
|
2161
|
-
let to;
|
|
2162
|
-
if (member.url === head.docUrl) {
|
|
2163
|
-
to = encodeHeads([head.hash]);
|
|
2164
|
-
} else {
|
|
2165
|
-
let pinnedIndex = -1;
|
|
2166
|
-
let bestTime = -Infinity;
|
|
2167
|
-
metas.forEach((m, i) => {
|
|
2168
|
-
if (m.time <= head.time && m.time >= bestTime) {
|
|
2169
|
-
bestTime = m.time;
|
|
2170
|
-
pinnedIndex = i;
|
|
2171
|
-
}
|
|
2172
|
-
});
|
|
2173
|
-
if (pinnedIndex < 0) continue;
|
|
2174
|
-
to = encodeHeads([metas[pinnedIndex].hash]);
|
|
2175
|
-
}
|
|
2176
|
-
checkpoint[member.url] = {
|
|
2177
|
-
from: to,
|
|
2178
|
-
to
|
|
2179
|
-
};
|
|
2180
|
-
} catch (err) {
|
|
2181
|
-
console.warn("[drafts] failed to compute checkpoint for member:", member, err);
|
|
2182
|
-
}
|
|
2183
|
-
}
|
|
2184
|
-
return checkpoint;
|
|
2185
|
-
}
|
|
2186
|
-
async function collectInterleavedChanges(repo, members, mainDocUrl) {
|
|
2187
|
-
const rows = [];
|
|
2188
|
-
const createdAt = await getDocCreationTime(repo, mainDocUrl);
|
|
2189
|
-
for (const member of members) {
|
|
2190
|
-
try {
|
|
2191
|
-
const handle = await repo.find(member.cloneUrl ?? member.url);
|
|
2192
|
-
const doc = handle.doc();
|
|
2193
|
-
if (!doc) continue;
|
|
2194
|
-
const since = member.clonedAt ? decodeHeads(member.clonedAt) : [];
|
|
2195
|
-
const metas = Automerge.getChangesMetaSince(doc, since);
|
|
2196
|
-
if (metas.length === 0) continue;
|
|
2197
|
-
const title = await resolveDocTitle(doc, member.url);
|
|
2198
|
-
metas.forEach((meta, seq) => {
|
|
2199
|
-
if (createdAt !== void 0 && meta.time && meta.time < createdAt) {
|
|
2200
|
-
return;
|
|
2201
|
-
}
|
|
2202
|
-
const {
|
|
2203
|
-
additions,
|
|
2204
|
-
deletions
|
|
2205
|
-
} = computeEditCounts(doc, meta.hash, meta.deps);
|
|
2206
|
-
rows.push({
|
|
2207
|
-
docUrl: member.url,
|
|
2208
|
-
title,
|
|
2209
|
-
hash: meta.hash,
|
|
2210
|
-
time: meta.time,
|
|
2211
|
-
actor: meta.actor,
|
|
2212
|
-
message: meta.message,
|
|
2213
|
-
seq,
|
|
2214
|
-
additions,
|
|
2215
|
-
deletions
|
|
2216
|
-
});
|
|
2217
|
-
});
|
|
2218
|
-
} catch (err) {
|
|
2219
|
-
console.warn("[drafts] failed to read changes for member:", member, err);
|
|
2220
|
-
}
|
|
2221
|
-
}
|
|
2222
|
-
rows.sort((a, b) => b.time - a.time || b.seq - a.seq);
|
|
2223
|
-
return rows;
|
|
2224
|
-
}
|
|
2225
|
-
function computeEditCounts(doc, hash, deps) {
|
|
2226
|
-
let additions = 0;
|
|
2227
|
-
let deletions = 0;
|
|
2228
|
-
try {
|
|
2229
|
-
const patches = Automerge.diff(doc, deps, [hash]);
|
|
2230
|
-
for (const patch of patches) {
|
|
2231
|
-
if (patch.path[0] === "@patchwork") continue;
|
|
2232
|
-
if (patch.action === "splice") {
|
|
2233
|
-
additions += patch.value.length;
|
|
2234
|
-
} else if (patch.action === "insert") {
|
|
2235
|
-
additions += Array.isArray(patch.values) ? patch.values.length : 1;
|
|
2236
|
-
} else if (patch.action === "del") {
|
|
2237
|
-
deletions += patch.length ?? 1;
|
|
2238
|
-
} else {
|
|
2239
|
-
additions += 1;
|
|
2240
|
-
}
|
|
2241
|
-
}
|
|
2242
|
-
} catch (err) {
|
|
2243
|
-
console.warn("[drafts] failed to diff change for edit counts:", hash, err);
|
|
2244
|
-
}
|
|
2245
|
-
return {
|
|
2246
|
-
additions,
|
|
2247
|
-
deletions
|
|
2248
|
-
};
|
|
2249
|
-
}
|
|
2250
|
-
async function getDocCreationTime(repo, url) {
|
|
2251
|
-
if (!url) return void 0;
|
|
2252
|
-
try {
|
|
2253
|
-
const handle = await repo.find(url);
|
|
2254
|
-
const doc = handle.doc();
|
|
2255
|
-
if (!doc) return void 0;
|
|
2256
|
-
const metas = Automerge.getChangesMetaSince(doc, []);
|
|
2257
|
-
return metas[0]?.time || void 0;
|
|
2258
|
-
} catch (err) {
|
|
2259
|
-
console.warn("[drafts] failed to resolve creation time for:", url, err);
|
|
2260
|
-
return void 0;
|
|
2261
|
-
}
|
|
2262
|
-
}
|
|
2263
|
-
async function resolveDocTitle(doc, url) {
|
|
2264
|
-
try {
|
|
2265
|
-
const meta = doc["@patchwork"];
|
|
2266
|
-
if (typeof meta?.title === "string" && meta.title) return meta.title;
|
|
2267
|
-
const type = meta?.type;
|
|
2268
|
-
if (type) {
|
|
2269
|
-
const registry = getRegistry("patchwork:datatype");
|
|
2270
|
-
const datatype = registry.get(type);
|
|
2271
|
-
if (datatype) {
|
|
2272
|
-
await registry.load(datatype.id);
|
|
2273
|
-
if (isLoadedPlugin(datatype)) {
|
|
2274
|
-
const title = datatype.module.getTitle(doc);
|
|
2275
|
-
if (title) return title;
|
|
2276
|
-
}
|
|
2277
|
-
}
|
|
2278
|
-
}
|
|
2279
|
-
} catch (err) {
|
|
2280
|
-
console.warn("[drafts] failed to resolve title for:", url, err);
|
|
2281
|
-
}
|
|
2282
|
-
return shortUrl(url);
|
|
2283
|
-
}
|
|
2284
|
-
function shortUrl(url) {
|
|
2285
|
-
const id = url.replace(/^automerge:/, "");
|
|
2286
|
-
if (id.length <= 10) return id;
|
|
2287
|
-
return `${id.slice(0, 6)}…${id.slice(-4)}`;
|
|
2288
|
-
}
|
|
2289
|
-
function authorColor(authorId) {
|
|
2290
|
-
let hash = 0;
|
|
2291
|
-
for (let i = 0; i < authorId.length; i++) {
|
|
2292
|
-
hash = authorId.charCodeAt(i) + ((hash << 5) - hash);
|
|
2293
|
-
}
|
|
2294
|
-
const h = Math.abs(hash) % 360;
|
|
2295
|
-
return `hsl(${h}, 45%, 63%)`;
|
|
2296
|
-
}
|
|
2297
|
-
function getInitials(authorId) {
|
|
2298
|
-
return authorId.slice(0, 2).toUpperCase();
|
|
2299
|
-
}
|
|
2300
|
-
function formatTime(timeSeconds) {
|
|
2301
|
-
if (!timeSeconds) return "";
|
|
2302
|
-
const date = new Date(timeSeconds * 1e3);
|
|
2303
|
-
const datePart = date.toLocaleDateString(void 0, {
|
|
2304
|
-
month: "short",
|
|
2305
|
-
day: "numeric"
|
|
2306
|
-
});
|
|
2307
|
-
const timePart = date.toLocaleTimeString(void 0, {
|
|
2308
|
-
hour: "numeric",
|
|
2309
|
-
minute: "2-digit",
|
|
2310
|
-
second: "2-digit",
|
|
2311
|
-
hour12: true
|
|
2312
|
-
});
|
|
2313
|
-
return `${datePart}, ${timePart}`;
|
|
2314
|
-
}
|
|
2315
|
-
delegateEvents(["click", "dblclick", "keydown", "pointerdown"]);
|
|
2316
|
-
const renderDraftsSidebar = (_handle, element) => {
|
|
2317
|
-
return render(() => createComponent(RepoContext.Provider, {
|
|
2318
|
-
get value() {
|
|
2319
|
-
return element.repo;
|
|
2320
|
-
},
|
|
2321
|
-
get children() {
|
|
2322
|
-
return createComponent(DraftsSidebar, {
|
|
2323
|
-
element
|
|
2324
|
-
});
|
|
2325
|
-
}
|
|
2326
|
-
}), element);
|
|
2327
|
-
};
|
|
2328
|
-
export {
|
|
2329
|
-
renderDraftsSidebar
|
|
2330
|
-
};
|
|
2331
|
-
//# sourceMappingURL=main-Cp8VsNHh.js.map
|