@pipeup/share 0.9.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -147,130 +147,133 @@ var P = 2n ** 256n - 2n ** 32n - 977n;
147
147
  // ../pipeup/dist/pipeup.core.js
148
148
  function e(e3) {
149
149
  let t2 = "";
150
- for (let r2 of e3) t2 += String.fromCharCode(r2);
150
+ for (let n2 of e3) t2 += String.fromCharCode(n2);
151
151
  return btoa(t2).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
152
152
  }
153
153
  function t(e3) {
154
- let t2 = atob(e3.replace(/-/g, "+").replace(/_/g, "/")), r2 = new Uint8Array(t2.length);
155
- for (let e4 = 0; e4 < t2.length; e4++) r2[e4] = t2.charCodeAt(e4);
156
- return r2;
154
+ let t2 = atob(e3.replace(/-/g, "+").replace(/_/g, "/")), n2 = new Uint8Array(t2.length);
155
+ for (let e4 = 0; e4 < t2.length; e4++) n2[e4] = t2.charCodeAt(e4);
156
+ return n2;
157
157
  }
158
- function r(e3) {
158
+ function n(e3) {
159
159
  return new TextEncoder().encode(e3);
160
160
  }
161
- function n(e3) {
161
+ function r(e3) {
162
162
  if (null === e3 || "object" != typeof e3) return JSON.stringify(e3);
163
- if (Array.isArray(e3)) return "[" + e3.map(n).join(",") + "]";
163
+ if (Array.isArray(e3)) return "[" + e3.map(r).join(",") + "]";
164
164
  let t2 = e3;
165
- return "{" + Object.keys(t2).filter((e4) => void 0 !== t2[e4]).sort().map((e4) => JSON.stringify(e4) + ":" + n(t2[e4])).join(",") + "}";
165
+ return "{" + Object.keys(t2).filter((e4) => void 0 !== t2[e4]).sort().map((e4) => JSON.stringify(e4) + ":" + r(t2[e4])).join(",") + "}";
166
166
  }
167
167
  var o = /^[A-Za-z0-9_-]{43}$/;
168
168
  var s = /* @__PURE__ */ new Map();
169
- async function d() {
169
+ async function l() {
170
170
  let t2 = await crypto.subtle.generateKey({ name: "Ed25519" }, false, ["sign", "verify"]);
171
171
  return { publicKey: e(new Uint8Array(await crypto.subtle.exportKey("raw", t2.publicKey))), privateKey: t2.privateKey };
172
172
  }
173
- async function l(t2, r2) {
174
- let n2 = await crypto.subtle.sign({ name: "Ed25519" }, t2.privateKey, r2);
175
- return e(new Uint8Array(n2));
173
+ async function d(t2, n2) {
174
+ let r2 = await crypto.subtle.sign({ name: "Ed25519" }, t2.privateKey, n2);
175
+ return e(new Uint8Array(r2));
176
176
  }
177
177
  var u = ["Otter", "Fox", "Owl", "Bear", "Rabbit"];
178
- var c = ["Red", "Orange", "Yellow", "Green", "Teal", "Blue", "Purple", "Pink", "Brown", "Grey"];
179
- function h(e3) {
178
+ var h = ["Red", "Orange", "Yellow", "Green", "Teal", "Blue", "Purple", "Pink", "Brown", "Grey"];
179
+ function c(e3) {
180
180
  let t2 = 2166136261;
181
- for (let r2 = 0; r2 < e3.length; r2++) t2 = Math.imul(t2 ^ e3.charCodeAt(r2), 16777619);
181
+ for (let n2 = 0; n2 < e3.length; n2++) t2 = Math.imul(t2 ^ e3.charCodeAt(n2), 16777619);
182
182
  return t2 = Math.imul(t2 ^ t2 >>> 16, 2246822507), t2 = Math.imul(t2 ^ t2 >>> 13, 3266489909), (t2 ^ t2 >>> 16) >>> 0;
183
183
  }
184
- var p = (e3) => `${c[((e4) => Math.floor(h(e4) / u.length) % c.length)(e3)]} ${u[((e4) => h(e4) % u.length)(e3)]}`;
184
+ var p = (e3) => `${h[((e4) => Math.floor(c(e4) / u.length) % h.length)(e3)]} ${u[((e4) => c(e4) % u.length)(e3)]}`;
185
185
  var f = (e3) => {
186
186
  let t2 = e3.name.replace(/^AI assistant \xb7 /, "") || p(e3.author);
187
187
  return e3.alike ? `${t2} \xB7 ${(function(e4) {
188
- let t3 = h(`id:${e4}`), r2 = "";
189
- for (let e5 = 0; e5 < 4; e5++, t3 >>>= 5) r2 += "0123456789ABCDEFGHJKMNPQRSTVWXYZ"[31 & t3];
190
- return r2;
188
+ let t3 = c(`id:${e4}`), n2 = "";
189
+ for (let e5 = 0; e5 < 4; e5++, t3 >>>= 5) n2 += "0123456789ABCDEFGHJKMNPQRSTVWXYZ"[31 & t3];
190
+ return n2;
191
191
  })(e3.author)}` : t2;
192
192
  };
193
193
  var m = "AI assistant";
194
194
  var g = (e3) => e3 === m || e3.startsWith(`${m} `);
195
195
  var y = (e3) => `${m} \xB7 ${e3.replace(/\s+/g, " ").trim() || "Agent"}`.slice(0, 80).trim();
196
196
  var b = 1e4;
197
- var x = 2 ** 40;
198
- var v = 2 ** 47;
197
+ var v = 2 ** 40;
198
+ var x = 2 ** 47;
199
199
  var k = 1e4;
200
- var A = /^[0-9a-f]{8}$/;
201
- var E = /^[A-Za-z0-9_-]{43}$/;
202
- var $ = /^(?:[^\s@<>"]{1,64}@[^\s@<>"]{1,190}\.[^\s@<>"]{2,24}|gh:[A-Za-z0-9-]{1,39})$/;
203
- var S = /^(?:[A-Za-z0-9_-]{43}|(?:host|gh):[A-Za-z0-9._@-]{1,64})$/;
204
- var M = /^[A-Za-z0-9_-]{43}$/;
205
- var C = /* @__PURE__ */ new Set(["create", "reply", "edit", "delete", "resolve", "reopen", "addressed", "react", "unreact", "seen", "contact", "uncontact"]);
206
- var N = /^(?:\p{Regional_Indicator}{2}|[#*0-9]\uFE0F?\u20E3|\p{Extended_Pictographic}(?:\uFE0F|\p{Emoji_Modifier})?(?:\u200D\p{Extended_Pictographic}(?:\uFE0F|\p{Emoji_Modifier})?)*)$/u;
207
- var O = (e3) => "string" == typeof e3 && N.test(e3) && [...e3].length <= 16;
208
- async function q(e3, t2) {
200
+ var A = 200;
201
+ var $ = /* @__PURE__ */ new Set(["h", "p", "img", "button", "link", "field", "media", "box"]);
202
+ var E = /* @__PURE__ */ new Set(["confirmed", "moved", "gone"]);
203
+ var M = /^[0-9a-f]{8}$/;
204
+ var S = /^[A-Za-z0-9_-]{43}$/;
205
+ var C = /^(?:[^\s@<>"]{1,64}@[^\s@<>"]{1,190}\.[^\s@<>"]{2,24}|gh:[A-Za-z0-9-]{1,39})$/;
206
+ var N = /^(?:[A-Za-z0-9_-]{43}|(?:host|gh):[A-Za-z0-9._@-]{1,64})$/;
207
+ var O = /^[A-Za-z0-9_-]{43}$/;
208
+ var q = /* @__PURE__ */ new Set(["create", "reply", "edit", "delete", "resolve", "reopen", "addressed", "react", "unreact", "seen", "contact", "uncontact", "place"]);
209
+ var j = /^(?:\p{Regional_Indicator}{2}|[#*0-9]\uFE0F?\u20E3|\p{Extended_Pictographic}(?:\uFE0F|\p{Emoji_Modifier})?(?:\u200D\p{Extended_Pictographic}(?:\uFE0F|\p{Emoji_Modifier})?)*)$/u;
210
+ var P2 = (e3) => "string" == typeof e3 && j.test(e3) && [...e3].length <= 16;
211
+ async function T(e3, t2) {
209
212
  if (e3.author !== t2.publicKey) throw new Error("pipeup: an op must be signed by its author");
210
- return { body: e3, sig: await l(t2, r(n(e3))) };
213
+ return { body: e3, sig: await d(t2, n(r(e3))) };
211
214
  }
212
- var j = (e3, t2) => "string" == typeof e3 && e3.length <= t2;
213
- var P2 = (e3) => !!e3 && "object" == typeof e3;
214
- var T = (e3) => "number" == typeof e3 && Number.isFinite(e3) && e3 >= 0 && e3 <= 1;
215
- function I(e3) {
216
- if (!P2(e3)) return false;
217
- let { id: t2, path: r2, fingerprint: n2, snapshot: i, quote: a, point: o2, view: s2 } = e3;
218
- if (!(j(r2, 2e3) && j(i, 500) && "string" == typeof n2 && A.test(n2) && (void 0 === t2 || j(t2, 200) && "" !== t2) && (void 0 === a || P2(a) && j(a.exact, k) && "" !== a.exact && j(a.prefix, 64) && j(a.suffix, 64)) && (void 0 === o2 || P2(o2) && T(o2.x) && T(o2.y)))) return false;
215
+ var I = (e3, t2) => "string" == typeof e3 && e3.length <= t2;
216
+ var L = (e3) => !!e3 && "object" == typeof e3;
217
+ var F = (e3) => "number" == typeof e3 && Number.isFinite(e3) && e3 >= 0 && e3 <= 1;
218
+ function R(e3) {
219
+ if (!L(e3)) return false;
220
+ let { id: t2, path: n2, fingerprint: r2, snapshot: i, quote: a, point: o2, view: s2, kind: l2, name: d2, heads: u2, y: h2, lost: c2 } = e3;
221
+ if (!(I(n2, 2e3) && I(i, 500) && "string" == typeof r2 && M.test(r2) && (void 0 === t2 || I(t2, 200) && "" !== t2) && (void 0 === a || L(a) && I(a.exact, k) && "" !== a.exact && I(a.prefix, 64) && I(a.suffix, 64)) && (void 0 === o2 || L(o2) && F(o2.x) && F(o2.y)))) return false;
219
222
  if (void 0 !== s2) {
220
- if (!P2(s2) || Array.isArray(s2)) return false;
223
+ if (!L(s2) || Array.isArray(s2)) return false;
221
224
  let e4 = Object.entries(s2);
222
- if (e4.length > 16 || !e4.every(([e5, t3]) => e5.length <= 64 && j(t3, 200))) return false;
225
+ if (e4.length > 16 || !e4.every(([e5, t3]) => e5.length <= 64 && I(t3, 200))) return false;
223
226
  }
224
- return true;
227
+ return !(void 0 !== l2 && !$.has(l2) || void 0 !== d2 && !I(d2, A) || void 0 !== u2 && (!Array.isArray(u2) || u2.length > 3 || !u2.every((e4) => I(e4, 120))) || void 0 !== h2 && !F(h2) || void 0 !== c2 && true !== c2);
225
228
  }
226
- function F(e3) {
227
- if (!P2(e3)) return false;
228
- let { body: t2, sig: r2 } = e3;
229
- if ("string" != typeof r2 || !P2(t2) || JSON.stringify({ body: t2, sig: r2 }).length > 262144) return false;
230
- let n2 = t2;
231
- if (1 !== n2.v || "string" != typeof n2.id || !E.test(n2.id) || !C.has(n2.kind) || !j(n2.doc, 64) || "" === n2.doc || "string" != typeof n2.thread || !E.test(n2.thread) || "string" != typeof n2.author || !M.test(n2.author) || "string" != typeof n2.name || n2.name.length > 80 || n2.name !== n2.name.trim() || "number" != typeof n2.clock || !Number.isSafeInteger(n2.clock) || n2.clock < 1 || n2.clock > x || "number" != typeof n2.at || !Number.isSafeInteger(n2.at) || n2.at < 0 || n2.at > v || void 0 !== n2.text && (!j(n2.text, b) || n2.text !== n2.text.trim()) || void 0 !== n2.target && ("string" != typeof n2.target || !E.test(n2.target)) || ("create" === n2.kind || "reply" === n2.kind || "edit" === n2.kind || "addressed" === n2.kind) && !n2.text || ("reply" === n2.kind || "edit" === n2.kind || "delete" === n2.kind) && !n2.target) return false;
232
- if (void 0 !== n2.mentions) {
233
- if ("create" !== n2.kind && "reply" !== n2.kind && "edit" !== n2.kind || !Array.isArray(n2.mentions) || n2.mentions.length > 20) return false;
234
- let e4 = n2.text?.length ?? 0;
235
- for (let t3 of n2.mentions) {
236
- if (!P2(t3) || !Number.isSafeInteger(t3.start) || !Number.isSafeInteger(t3.end)) return false;
237
- let { start: r3, end: n3, ref: i } = t3;
238
- if (r3 < 0 || n3 <= r3 || n3 > e4 || "string" != typeof i || !S.test(i)) return false;
229
+ function D(e3) {
230
+ if (!L(e3)) return false;
231
+ let { body: t2, sig: n2 } = e3;
232
+ if ("string" != typeof n2 || !L(t2) || JSON.stringify({ body: t2, sig: n2 }).length > 262144) return false;
233
+ let r2 = t2;
234
+ if (1 !== r2.v || "string" != typeof r2.id || !S.test(r2.id) || !q.has(r2.kind) || !I(r2.doc, 64) || "" === r2.doc || "string" != typeof r2.thread || !S.test(r2.thread) || "string" != typeof r2.author || !O.test(r2.author) || "string" != typeof r2.name || r2.name.length > 80 || r2.name !== r2.name.trim() || "number" != typeof r2.clock || !Number.isSafeInteger(r2.clock) || r2.clock < 1 || r2.clock > v || "number" != typeof r2.at || !Number.isSafeInteger(r2.at) || r2.at < 0 || r2.at > x || void 0 !== r2.text && (!I(r2.text, b) || r2.text !== r2.text.trim()) || void 0 !== r2.target && ("string" != typeof r2.target || !S.test(r2.target)) || ("create" === r2.kind || "reply" === r2.kind || "edit" === r2.kind || "addressed" === r2.kind) && !r2.text || ("reply" === r2.kind || "edit" === r2.kind || "delete" === r2.kind) && !r2.target) return false;
235
+ if (void 0 !== r2.mentions) {
236
+ if ("create" !== r2.kind && "reply" !== r2.kind && "edit" !== r2.kind || !Array.isArray(r2.mentions) || r2.mentions.length > 20) return false;
237
+ let e4 = r2.text?.length ?? 0;
238
+ for (let t3 of r2.mentions) {
239
+ if (!L(t3) || !Number.isSafeInteger(t3.start) || !Number.isSafeInteger(t3.end)) return false;
240
+ let { start: n3, end: r3, ref: i } = t3;
241
+ if (n3 < 0 || r3 <= n3 || r3 > e4 || "string" != typeof i || !N.test(i)) return false;
239
242
  }
240
243
  }
241
- return !(!("contact" !== n2.kind || "string" == typeof n2.text && $.test(n2.text)) || "seen" === n2.kind && !n2.target || !("react" !== n2.kind && "unreact" !== n2.kind || n2.target && O(n2.text)) || !("create" !== n2.kind || n2.id === n2.thread && I(n2.anchor)));
244
+ return !!(("contact" !== r2.kind || "string" == typeof r2.text && C.test(r2.text)) && ("seen" !== r2.kind || r2.target) && ("react" !== r2.kind && "unreact" !== r2.kind || r2.target && P2(r2.text)) && ("create" !== r2.kind || r2.id === r2.thread && R(r2.anchor)) && ("place" !== r2.kind || R(r2.anchor) && E.has(r2.text)));
242
245
  }
243
- function L(i) {
244
- return (async function(r2, n2, i2) {
245
- if (!o.test(r2)) return false;
246
+ function U(i) {
247
+ return (async function(n2, r2, i2) {
248
+ if (!o.test(n2)) return false;
246
249
  try {
247
- if (e(t(r2)) !== r2) return false;
248
- let a = s.get(r2);
250
+ if (e(t(n2)) !== n2) return false;
251
+ let a = s.get(n2);
249
252
  if (!a) {
250
- s.size >= 512 && s.delete(s.keys().next().value), a = crypto.subtle.importKey("raw", t(r2), { name: "Ed25519" }, true, ["verify"]), s.set(r2, a);
253
+ s.size >= 512 && s.delete(s.keys().next().value), a = crypto.subtle.importKey("raw", t(n2), { name: "Ed25519" }, true, ["verify"]), s.set(n2, a);
251
254
  let e3 = a;
252
255
  e3.catch(() => {
253
- s.get(r2) === e3 && s.delete(r2);
256
+ s.get(n2) === e3 && s.delete(n2);
254
257
  });
255
258
  }
256
- return await crypto.subtle.verify({ name: "Ed25519" }, await a, t(i2), n2);
259
+ return await crypto.subtle.verify({ name: "Ed25519" }, await a, t(i2), r2);
257
260
  } catch {
258
261
  return false;
259
262
  }
260
- })(i.body.author, r(n(i.body)), i.sig);
263
+ })(i.body.author, n(r(i.body)), i.sig);
261
264
  }
262
- function D(e3, t2) {
265
+ function _(e3, t2) {
263
266
  return e3.body.clock !== t2.body.clock ? e3.body.clock - t2.body.clock : e3.body.at !== t2.body.at ? e3.body.at - t2.body.at : e3.body.author !== t2.body.author ? e3.body.author < t2.body.author ? -1 : 1 : e3.body.id !== t2.body.id ? e3.body.id < t2.body.id ? -1 : 1 : 0;
264
267
  }
265
- function U(e3, t2, r2, n2, i, a) {
266
- let o2 = { id: e3, author: t2, name: r2, text: n2, at: i, edited: false, deleted: false, replies: [], reactions: [] };
268
+ function z(e3, t2, n2, r2, i, a) {
269
+ let o2 = { id: e3, author: t2, name: n2, text: r2, at: i, edited: false, deleted: false, replies: [], reactions: [] };
267
270
  return a?.length && (o2.mentions = a), o2;
268
271
  }
269
- async function B(t2) {
270
- let i = { ...t2, id: void 0, thread: "create" === t2.kind ? void 0 : t2.thread }, a = await crypto.subtle.digest("SHA-256", r(n(i)));
272
+ async function H(t2) {
273
+ let i = { ...t2, id: void 0, thread: "create" === t2.kind ? void 0 : t2.thread }, a = await crypto.subtle.digest("SHA-256", n(r(i)));
271
274
  return e(new Uint8Array(a));
272
275
  }
273
- var _ = class {
276
+ var K = class {
274
277
  constructor(e3) {
275
278
  this.doc = e3;
276
279
  }
@@ -286,12 +289,12 @@ var _ = class {
286
289
  }
287
290
  threads() {
288
291
  return (function(e3) {
289
- let t2 = /* @__PURE__ */ new Map(), r2 = /* @__PURE__ */ new Map(), n2 = /* @__PURE__ */ new Map();
290
- for (let { body: i2 } of [...e3].sort(D)) {
291
- if (i2.name && !g(i2.name) && n2.set(i2.author, i2.name), "create" === i2.kind) {
292
+ let t2 = /* @__PURE__ */ new Map(), n2 = /* @__PURE__ */ new Map(), r2 = /* @__PURE__ */ new Map();
293
+ for (let { body: i2 } of [...e3].sort(_)) {
294
+ if (i2.name && !g(i2.name) && r2.set(i2.author, i2.name), "create" === i2.kind) {
292
295
  if (t2.has(i2.id) || !i2.anchor || void 0 === i2.text) continue;
293
- let e5 = U(i2.id, i2.author, i2.name, i2.text, i2.at, i2.mentions);
294
- t2.set(i2.id, { id: i2.id, anchor: i2.anchor, root: e5, resolved: false }), r2.set(i2.id, { comment: e5, thread: i2.id });
296
+ let e5 = z(i2.id, i2.author, i2.name, i2.text, i2.at, i2.mentions);
297
+ t2.set(i2.id, { id: i2.id, anchor: i2.anchor, root: e5, resolved: false }), n2.set(i2.id, { comment: e5, thread: i2.id });
295
298
  continue;
296
299
  }
297
300
  let e4 = t2.get(i2.thread);
@@ -300,16 +303,21 @@ var _ = class {
300
303
  e4.resolved = "resolve" === i2.kind, "reopen" === i2.kind && delete e4.addressed;
301
304
  continue;
302
305
  }
306
+ if ("place" === i2.kind) {
307
+ if (!i2.anchor) continue;
308
+ e4.anchor = i2.anchor, e4.placed = { how: i2.text, author: i2.author, name: i2.name, at: i2.at };
309
+ continue;
310
+ }
303
311
  if ("addressed" === i2.kind) {
304
312
  void 0 !== i2.text && (e4.addressed = { text: i2.text, author: i2.author, name: i2.name, at: i2.at });
305
313
  continue;
306
314
  }
307
- let a2 = i2.target ? r2.get(i2.target) : void 0;
315
+ let a2 = i2.target ? n2.get(i2.target) : void 0;
308
316
  if (a2 && a2.thread === i2.thread) {
309
317
  if ("reply" === i2.kind) {
310
- if (r2.has(i2.id) || void 0 === i2.text) continue;
311
- let t3 = U(i2.id, i2.author, i2.name, i2.text, i2.at, i2.mentions);
312
- e4.root.replies.push(t3), r2.set(i2.id, { comment: t3, thread: i2.thread });
318
+ if (n2.has(i2.id) || void 0 === i2.text) continue;
319
+ let t3 = z(i2.id, i2.author, i2.name, i2.text, i2.at, i2.mentions);
320
+ e4.root.replies.push(t3), n2.set(i2.id, { comment: t3, thread: i2.thread });
313
321
  continue;
314
322
  }
315
323
  if ("seen" === i2.kind) {
@@ -321,28 +329,28 @@ var _ = class {
321
329
  if (void 0 === i2.text || a2.comment.deleted) continue;
322
330
  let e5 = a2.comment.reactions, t3 = e5.find((e6) => e6.emoji === i2.text);
323
331
  if ("react" === i2.kind) {
324
- let r3 = { author: i2.author, name: i2.name };
325
- t3 ? t3.by.some((e6) => e6.author === i2.author) || t3.by.push(r3) : e5.length < 12 && e5.push({ emoji: i2.text, by: [r3] });
332
+ let n3 = { author: i2.author, name: i2.name };
333
+ t3 ? t3.by.some((e6) => e6.author === i2.author) || t3.by.push(n3) : e5.length < 12 && e5.push({ emoji: i2.text, by: [n3] });
326
334
  } else t3 && (t3.by = t3.by.filter((e6) => e6.author !== i2.author), t3.by.length || e5.splice(e5.indexOf(t3), 1));
327
335
  continue;
328
336
  }
329
337
  i2.author !== a2.comment.author || a2.comment.deleted || ("edit" === i2.kind && void 0 !== i2.text && (a2.comment.text = i2.text, a2.comment.edited = true, i2.mentions ? a2.comment.mentions = i2.mentions : delete a2.comment.mentions), "delete" === i2.kind && (a2.comment.text = "", a2.comment.deleted = true, a2.comment.reactions = [], delete a2.comment.mentions));
330
338
  }
331
339
  }
332
- for (let { comment: e4 } of r2.values()) {
333
- e4.name || (e4.unnamed = true, e4.name = n2.get(e4.author) ?? "");
334
- for (let t3 of e4.reactions) for (let e5 of t3.by) e5.name ||= n2.get(e5.author) ?? "";
340
+ for (let { comment: e4 } of n2.values()) {
341
+ e4.name || (e4.unnamed = true, e4.name = r2.get(e4.author) ?? "");
342
+ for (let t3 of e4.reactions) for (let e5 of t3.by) e5.name ||= r2.get(e5.author) ?? "";
335
343
  }
336
344
  let i = /* @__PURE__ */ new Map(), a = (e4, t3) => {
337
- let r3 = f({ author: e4, name: t3 }).toLowerCase();
338
- (i.get(r3) ?? i.set(r3, /* @__PURE__ */ new Set()).get(r3)).add(e4);
345
+ let n3 = f({ author: e4, name: t3 }).toLowerCase();
346
+ (i.get(n3) ?? i.set(n3, /* @__PURE__ */ new Set()).get(n3)).add(e4);
339
347
  };
340
- for (let { comment: e4 } of r2.values()) {
348
+ for (let { comment: e4 } of n2.values()) {
341
349
  a(e4.author, e4.name);
342
350
  for (let t3 of e4.reactions) for (let e5 of t3.by) a(e5.author, e5.name);
343
351
  }
344
352
  let o2 = (e4, t3) => !g(t3) && (i.get(f({ author: e4, name: t3 }).toLowerCase())?.size ?? 0) > 1;
345
- for (let { comment: e4 } of r2.values()) {
353
+ for (let { comment: e4 } of n2.values()) {
346
354
  o2(e4.author, e4.name) && (e4.alike = true);
347
355
  for (let t3 of e4.reactions) for (let e5 of t3.by) o2(e5.author, e5.name) && (e5.alike = true);
348
356
  }
@@ -351,41 +359,41 @@ var _ = class {
351
359
  }
352
360
  async add(e3) {
353
361
  let t2 = [];
354
- for (let r2 of e3) {
355
- if (!F(r2) || r2.body.doc !== this.doc || this.ops.has(r2.body.id) || r2.body.id !== await B(r2.body) || !await L(r2)) continue;
356
- let e4 = { body: r2.body, sig: r2.sig };
362
+ for (let n2 of e3) {
363
+ if (!D(n2) || n2.body.doc !== this.doc || this.ops.has(n2.body.id) || n2.body.id !== await H(n2.body) || !await U(n2)) continue;
364
+ let e4 = { body: n2.body, sig: n2.sig };
357
365
  this.ops.set(e4.body.id, e4), this.clock = Math.max(this.clock, e4.body.clock), "create" === e4.body.kind && this.createAt.set(e4.body.author, Math.max(this.createAt.get(e4.body.author) ?? 0, e4.body.at)), this.threadAt.set(e4.body.thread, Math.max(this.threadAt.get(e4.body.thread) ?? 0, e4.body.at)), t2.push(e4);
358
366
  }
359
367
  return t2;
360
368
  }
361
- async append(e3, t2, r2) {
362
- let n2 = { v: 1, ...r2, id: "", thread: "create" === r2.kind ? "" : r2.thread, doc: this.doc, author: e3.publicKey, name: t2, clock: Math.min(this.clock + 1, x), at: Math.min(Math.max(Date.now(), "create" === r2.kind ? (this.createAt.get(e3.publicKey) ?? 0) + 1 : (this.threadAt.get(r2.thread) ?? 0) + 1), v) };
363
- n2.id = await B(n2);
364
- let i = this.ops.get(n2.id);
369
+ async append(e3, t2, n2) {
370
+ let r2 = { v: 1, ...n2, id: "", thread: "create" === n2.kind ? "" : n2.thread, doc: this.doc, author: e3.publicKey, name: t2, clock: Math.min(this.clock + 1, v), at: Math.min(Math.max(Date.now(), "create" === n2.kind ? (this.createAt.get(e3.publicKey) ?? 0) + 1 : (this.threadAt.get(n2.thread) ?? 0) + 1), x) };
371
+ r2.id = await H(r2);
372
+ let i = this.ops.get(r2.id);
365
373
  if (i) return i;
366
- "create" === n2.kind && (n2.thread = n2.id);
367
- let [a] = await this.add([await q(n2, e3)]);
374
+ "create" === r2.kind && (r2.thread = r2.id);
375
+ let [a] = await this.add([await T(r2, e3)]);
368
376
  if (!a) throw new Error("pipeup: could not record this change");
369
377
  return a;
370
378
  }
371
379
  };
372
- var z = /^([A-Za-z0-9_-]{16}):([A-Za-z0-9_-]{43})$/;
373
- function H() {
380
+ var G = /^([A-Za-z0-9_-]{16}):([A-Za-z0-9_-]{43})$/;
381
+ function Z() {
374
382
  return `${(function(t2 = 16) {
375
383
  return e(crypto.getRandomValues(new Uint8Array(t2)));
376
384
  })(12)}:${e(crypto.getRandomValues(new Uint8Array(32)))}`;
377
385
  }
378
- async function K(e3) {
379
- let r2 = z.exec(e3.trim()), n2 = r2?.[1], i = r2?.[2];
380
- if (!n2 || !i) throw new Error('pipeup: data-pipeup-doc must look like "<id>:<key>", as made by newDocumentAttribute()');
381
- return { id: n2, key: await crypto.subtle.importKey("raw", t(i), { name: "AES-GCM" }, false, ["encrypt", "decrypt"]) };
386
+ async function J(e3) {
387
+ let n2 = G.exec(e3.trim()), r2 = n2?.[1], i = n2?.[2];
388
+ if (!r2 || !i) throw new Error('pipeup: data-pipeup-doc must look like "<id>:<key>", as made by newDocumentAttribute()');
389
+ return { id: r2, key: await crypto.subtle.importKey("raw", t(i), { name: "AES-GCM" }, false, ["encrypt", "decrypt"]) };
382
390
  }
383
- async function G(t2, n2, i) {
384
- let a = crypto.getRandomValues(new Uint8Array(12)), o2 = await crypto.subtle.encrypt({ name: "AES-GCM", iv: a, additionalData: r(i) }, t2, r(n2));
391
+ async function V(t2, r2, i) {
392
+ let a = crypto.getRandomValues(new Uint8Array(12)), o2 = await crypto.subtle.encrypt({ name: "AES-GCM", iv: a, additionalData: n(i) }, t2, n(r2));
385
393
  return { iv: e(a), data: e(new Uint8Array(o2)) };
386
394
  }
387
- var Z = (e3) => `pipeup-file:${e3}`;
388
- async function J(e3, n2, i) {
395
+ var W = (e3) => `pipeup-file:${e3}`;
396
+ async function Q(e3, r2, i) {
389
397
  if (e3.length > 5e6) throw new Error("pipeup: this feedback file is too large");
390
398
  let a, o2, s2;
391
399
  try {
@@ -394,19 +402,19 @@ async function J(e3, n2, i) {
394
402
  throw new Error("pipeup: this is not an Pipeup feedback file");
395
403
  }
396
404
  if (!a || "object" != typeof a || 1 !== a.pipeup || "string" != typeof a.doc) throw new Error("pipeup: this is not an Pipeup feedback file");
397
- if (a.doc !== n2) throw new Error("pipeup: this feedback is for a different document");
405
+ if (a.doc !== r2) throw new Error("pipeup: this feedback is for a different document");
398
406
  if (!a.sealed) return Array.isArray(a.ops) ? a.ops : [];
399
407
  if (!i) throw new Error("pipeup: this feedback is sealed, and this page has no document key");
400
408
  if ("string" != typeof a.iv || "string" != typeof a.data) throw new Error("pipeup: this is not an Pipeup feedback file");
401
409
  try {
402
- o2 = await (async function(e4, n3, i2) {
410
+ o2 = await (async function(e4, r3, i2) {
403
411
  try {
404
- let a2 = await crypto.subtle.decrypt({ name: "AES-GCM", iv: t(n3.iv), additionalData: r(i2) }, e4, t(n3.data));
412
+ let a2 = await crypto.subtle.decrypt({ name: "AES-GCM", iv: t(r3.iv), additionalData: n(i2) }, e4, t(r3.data));
405
413
  return new TextDecoder().decode(a2);
406
414
  } catch {
407
415
  throw new Error("pipeup: this feedback could not be opened with this document");
408
416
  }
409
- })(i, { iv: a.iv, data: a.data }, Z(n2));
417
+ })(i, { iv: a.iv, data: a.data }, W(r2));
410
418
  } catch {
411
419
  throw new Error("pipeup: this feedback could not be opened with this document's key");
412
420
  }
@@ -417,15 +425,15 @@ async function J(e3, n2, i) {
417
425
  }
418
426
  return Array.isArray(s2) ? s2 : [];
419
427
  }
420
- var V = /^[a-z][a-z0-9-]{1,23}\/[a-z][a-z0-9-]{0,31}$/;
421
- var W = class extends Error {
422
- constructor(e3, t2, r2 = 1) {
423
- super("pipeup: shown here, but not saved yet"), this.id = e3, this.cause = t2, this.count = r2, this.name = "UnsavedChangeError";
428
+ var X = /^[a-z][a-z0-9-]{1,23}\/[a-z][a-z0-9-]{0,31}$/;
429
+ var Y = class extends Error {
430
+ constructor(e3, t2, n2 = 1) {
431
+ super("pipeup: shown here, but not saved yet"), this.id = e3, this.cause = t2, this.count = n2, this.name = "UnsavedChangeError";
424
432
  }
425
433
  };
426
- var Q = class e2 {
434
+ var ee = class e2 {
427
435
  constructor(e3, t2) {
428
- this.log = e3, this.options = t2, this.displayName = t2.name.trim() ? ee(t2.name) : "";
436
+ this.log = e3, this.options = t2, this.displayName = t2.name.trim() ? re(t2.name) : "";
429
437
  }
430
438
  listeners = /* @__PURE__ */ new Set();
431
439
  cache = [];
@@ -435,9 +443,9 @@ var Q = class e2 {
435
443
  unsaved = [];
436
444
  static async open(t2) {
437
445
  if ("string" != typeof t2.doc || "" === t2.doc || t2.doc.length > 64) throw new Error("pipeup: the document id must be 1 to 64 characters");
438
- let r2 = new _(t2.doc), n2 = await t2.store.load(t2.doc), i = n2.length - (await r2.add(n2)).length;
446
+ let n2 = new K(t2.doc), r2 = await t2.store.load(t2.doc), i = r2.length - (await n2.add(r2)).length;
439
447
  i && console.warn(`pipeup: ${i} saved change${1 === i ? "" : "s"} on this page couldn't be read; kept as saved`);
440
- let a = new e2(r2, t2);
448
+ let a = new e2(n2, t2);
441
449
  return a.refresh(false), a;
442
450
  }
443
451
  get id() {
@@ -450,7 +458,7 @@ var Q = class e2 {
450
458
  return this.displayName;
451
459
  }
452
460
  set name(e3) {
453
- this.displayName = ee(e3), this.refresh(true, [], "");
461
+ this.displayName = re(e3), this.refresh(true, [], "");
454
462
  }
455
463
  threads() {
456
464
  return this.cache;
@@ -461,16 +469,22 @@ var Q = class e2 {
461
469
  onChange(e3) {
462
470
  return this.listeners.add(e3), () => this.listeners.delete(e3);
463
471
  }
464
- comment(e3, t2, r2) {
465
- return this.enqueue(() => this.write({ kind: "create", anchor: e3, text: X(t2), ...r2?.length ? { mentions: r2 } : {} }));
472
+ comment(e3, t2, n2) {
473
+ return this.enqueue(() => this.write({ kind: "create", anchor: e3, text: te(t2), ...n2?.length ? { mentions: n2 } : {} }));
474
+ }
475
+ place(e3, t2, n2) {
476
+ return this.enqueue(async () => {
477
+ let { thread: r2 } = this.find(e3), i = "gone" === n2 ? { ...t2, lost: true } : t2;
478
+ await this.write({ kind: "place", thread: r2, anchor: i, text: n2 });
479
+ });
466
480
  }
467
- reply(e3, t2, r2) {
468
- return this.enqueue(() => this.write({ kind: "reply", thread: this.find(e3).thread, target: e3, text: X(t2), ...r2?.length ? { mentions: r2 } : {} }));
481
+ reply(e3, t2, n2) {
482
+ return this.enqueue(() => this.write({ kind: "reply", thread: this.find(e3).thread, target: e3, text: te(t2), ...n2?.length ? { mentions: n2 } : {} }));
469
483
  }
470
- edit(e3, t2, r2) {
484
+ edit(e3, t2, n2) {
471
485
  return this.enqueue(async () => {
472
- let { thread: n2 } = this.mine(e3);
473
- await this.write({ kind: "edit", thread: n2, target: e3, text: X(t2), ...r2?.length ? { mentions: r2 } : {} });
486
+ let { thread: r2 } = this.mine(e3);
487
+ await this.write({ kind: "edit", thread: r2, target: e3, text: te(t2), ...n2?.length ? { mentions: n2 } : {} });
474
488
  });
475
489
  }
476
490
  remove(e3) {
@@ -481,7 +495,7 @@ var Q = class e2 {
481
495
  }
482
496
  contact(e3) {
483
497
  let t2 = e3.trim();
484
- return $.test(t2) ? this.enqueue(async () => {
498
+ return C.test(t2) ? this.enqueue(async () => {
485
499
  await this.write({ kind: "contact", thread: this.me, text: t2 });
486
500
  }) : Promise.reject(new Error("pipeup: that isn't an email address or a GitHub name"));
487
501
  }
@@ -492,7 +506,7 @@ var Q = class e2 {
492
506
  }
493
507
  contacts() {
494
508
  let e3 = /* @__PURE__ */ new Map();
495
- for (let { body: t2 } of [...this.log.all()].sort(D)) "contact" === t2.kind && t2.text ? e3.set(t2.author, t2.text) : "uncontact" === t2.kind && e3.delete(t2.author);
509
+ for (let { body: t2 } of [...this.log.all()].sort(_)) "contact" === t2.kind && t2.text ? e3.set(t2.author, t2.text) : "uncontact" === t2.kind && e3.delete(t2.author);
496
510
  return e3;
497
511
  }
498
512
  get portable() {
@@ -501,8 +515,8 @@ var Q = class e2 {
501
515
  async seed() {
502
516
  let e3 = this.options.identity.privateKey;
503
517
  if (!e3.extractable) return null;
504
- let { d: r2 } = await crypto.subtle.exportKey("jwk", e3);
505
- return r2 ? t(r2) : null;
518
+ let { d: n2 } = await crypto.subtle.exportKey("jwk", e3);
519
+ return n2 ? t(n2) : null;
506
520
  }
507
521
  seen(e3) {
508
522
  return this.enqueue(async () => {
@@ -514,12 +528,12 @@ var Q = class e2 {
514
528
  }
515
529
  react(e3, t2) {
516
530
  return this.enqueue(async () => {
517
- await this.write({ kind: "react", thread: this.find(e3).thread, target: e3, text: Y(t2) });
531
+ await this.write({ kind: "react", thread: this.find(e3).thread, target: e3, text: ne(t2) });
518
532
  });
519
533
  }
520
534
  unreact(e3, t2) {
521
535
  return this.enqueue(async () => {
522
- await this.write({ kind: "unreact", thread: this.find(e3).thread, target: e3, text: Y(t2) });
536
+ await this.write({ kind: "unreact", thread: this.find(e3).thread, target: e3, text: ne(t2) });
523
537
  });
524
538
  }
525
539
  resolve(e3) {
@@ -532,39 +546,39 @@ var Q = class e2 {
532
546
  await this.write({ kind: "reopen", thread: this.thread(e3) });
533
547
  });
534
548
  }
535
- paste(e3, t2, r2, n2) {
549
+ paste(e3, t2, n2, r2) {
536
550
  return this.enqueue(async () => {
537
551
  let i = this.thread(e3), a = y(t2), o2 = this.cache.find((e4) => e4.id === i).root.id;
538
- await this.write({ kind: "reply", thread: i, target: o2, text: X(r2) }, a), n2?.trim() && await this.write({ kind: "addressed", thread: i, text: X(n2) }, a);
552
+ await this.write({ kind: "reply", thread: i, target: o2, text: te(n2) }, a), r2?.trim() && await this.write({ kind: "addressed", thread: i, text: te(r2) }, a);
539
553
  });
540
554
  }
541
555
  sign(e3, t2) {
542
- if (!V.test(e3)) throw new Error('pipeup: a signing purpose looks like "<add-on id>/<name>"');
543
- return l(this.options.identity, r(`pipeup:${e3}
556
+ if (!X.test(e3)) throw new Error('pipeup: a signing purpose looks like "<add-on id>/<name>"');
557
+ return d(this.options.identity, n(`pipeup:${e3}
544
558
  ${t2}`));
545
559
  }
546
560
  flush() {
547
561
  return this.enqueue(() => this.persist());
548
562
  }
549
563
  exportFile() {
550
- return (async function(e3, t2, r2) {
551
- let n2 = r2 ? { pipeup: 1, doc: e3, sealed: true, ...await G(r2, JSON.stringify(t2), Z(e3)) } : { pipeup: 1, doc: e3, sealed: false, ops: t2 };
552
- return JSON.stringify(n2, null, 2);
564
+ return (async function(e3, t2, n2) {
565
+ let r2 = n2 ? { pipeup: 1, doc: e3, sealed: true, ...await V(n2, JSON.stringify(t2), W(e3)) } : { pipeup: 1, doc: e3, sealed: false, ops: t2 };
566
+ return JSON.stringify(r2, null, 2);
553
567
  })(this.options.doc, this.log.all(), this.options.key);
554
568
  }
555
569
  async importFile(e3) {
556
- return this.merge(await J(e3, this.options.doc, this.options.key), "file");
570
+ return this.merge(await Q(e3, this.options.doc, this.options.key), "file");
557
571
  }
558
572
  merge(e3, t2) {
559
573
  return e3.length > 5e3 ? Promise.reject(new RangeError("pipeup: too many changes to merge at once")) : this.enqueue(async () => {
560
- let r2 = await this.log.add([...e3]);
561
- this.unsaved.push(...r2), r2.length > 0 && this.refresh(true, r2, t2);
574
+ let n2 = await this.log.add([...e3]);
575
+ this.unsaved.push(...n2), n2.length > 0 && this.refresh(true, n2, t2);
562
576
  try {
563
577
  await this.persist();
564
578
  } catch (e4) {
565
- throw r2.length > 0 ? new W(r2[0].body.id, e4, r2.length) : e4;
579
+ throw n2.length > 0 ? new Y(n2[0].body.id, e4, n2.length) : e4;
566
580
  }
567
- return r2.length;
581
+ return n2.length;
568
582
  });
569
583
  }
570
584
  enqueue(e3) {
@@ -573,29 +587,29 @@ ${t2}`));
573
587
  }), t2;
574
588
  }
575
589
  async write(e3, t2 = this.displayName) {
576
- let r2 = await this.log.append(this.options.identity, t2, e3);
577
- this.unsaved.push(r2), this.refresh(true, [r2], "local");
590
+ let n2 = await this.log.append(this.options.identity, t2, e3);
591
+ this.unsaved.push(n2), this.refresh(true, [n2], "local");
578
592
  try {
579
593
  await this.persist();
580
594
  } catch (e4) {
581
- throw new W(r2.body.id, e4);
595
+ throw new Y(n2.body.id, e4);
582
596
  }
583
- return r2.body.id;
597
+ return n2.body.id;
584
598
  }
585
599
  async persist() {
586
600
  if (0 === this.unsaved.length) return;
587
601
  let e3 = [...this.unsaved];
588
602
  await this.options.store.append(this.options.doc, e3), this.unsaved = this.unsaved.filter((t2) => !e3.includes(t2));
589
603
  }
590
- refresh(e3, t2 = [], r2 = "") {
604
+ refresh(e3, t2 = [], n2 = "") {
591
605
  this.cache = this.log.threads(), this.comments.clear();
592
- let n2 = (e4, t3) => {
606
+ let r2 = (e4, t3) => {
593
607
  e4.unnamed && e4.author === this.me && this.displayName && (e4.name = this.displayName), this.comments.set(e4.id, { comment: e4, thread: t3 });
594
- for (let r3 of e4.replies) n2(r3, t3);
608
+ for (let n3 of e4.replies) r2(n3, t3);
595
609
  };
596
- for (let e4 of this.cache) n2(e4.root, e4.id);
610
+ for (let e4 of this.cache) r2(e4.root, e4.id);
597
611
  if (e3) for (let e4 of this.listeners) try {
598
- e4(this.cache, t2, r2);
612
+ e4(this.cache, t2, n2);
599
613
  } catch (e5) {
600
614
  globalThis.reportError?.(e5);
601
615
  }
@@ -615,32 +629,32 @@ ${t2}`));
615
629
  return e3;
616
630
  }
617
631
  };
618
- function X(e3) {
632
+ function te(e3) {
619
633
  let t2 = e3.trim();
620
634
  if (!t2) throw new Error("pipeup: a comment needs some words");
621
635
  if (t2.length > b) throw new Error(`pipeup: comments are limited to ${b} characters`);
622
636
  return t2;
623
637
  }
624
- function Y(e3) {
625
- if (!O(e3)) throw new Error("pipeup: a reaction is one emoji");
638
+ function ne(e3) {
639
+ if (!P2(e3)) throw new Error("pipeup: a reaction is one emoji");
626
640
  return e3;
627
641
  }
628
- function ee(e3) {
642
+ function re(e3) {
629
643
  let t2 = e3.replace(/\s+/g, " ").trim();
630
644
  if (!t2 || t2.length > 80) throw new Error("pipeup: choose a name of 1 to 80 characters");
631
645
  if (g(t2)) throw new Error("pipeup: that name is kept for AI replies; choose another");
632
646
  return t2;
633
647
  }
634
- var te = class {
648
+ var ie = class {
635
649
  docs = /* @__PURE__ */ new Map();
636
650
  profile = null;
637
651
  async load(e3) {
638
652
  return [...this.docs.get(e3)?.values() ?? []];
639
653
  }
640
654
  async append(e3, t2) {
641
- let r2 = this.docs.get(e3);
642
- r2 || this.docs.set(e3, r2 = /* @__PURE__ */ new Map());
643
- for (let e4 of t2) r2.set(e4.body.id, e4);
655
+ let n2 = this.docs.get(e3);
656
+ n2 || this.docs.set(e3, n2 = /* @__PURE__ */ new Map());
657
+ for (let e4 of t2) n2.set(e4.body.id, e4);
644
658
  }
645
659
  async loadProfile() {
646
660
  return this.profile;
@@ -1100,12 +1114,12 @@ function server(value, mailbox) {
1100
1114
  return mailbox ? value.replace(/\/+$/, "") : u2.origin + u2.pathname;
1101
1115
  }
1102
1116
  async function feedbackOps(file, docAttr, io) {
1103
- const { id, key } = await K(docAttr);
1104
- const doc = await Q.open({
1117
+ const { id, key } = await J(docAttr);
1118
+ const doc = await ee.open({
1105
1119
  doc: id,
1106
1120
  key,
1107
- store: new te(),
1108
- identity: await d(),
1121
+ store: new ie(),
1122
+ identity: await l(),
1109
1123
  name: ""
1110
1124
  });
1111
1125
  try {
@@ -1131,11 +1145,11 @@ Run the same command with --new-doc and I will write a fresh one into the page.
1131
1145
  );
1132
1146
  throw new UsageError("the page needs a document identity");
1133
1147
  }
1134
- docAttr = H();
1148
+ docAttr = Z();
1135
1149
  html = setAttribute(html, "data-pipeup-doc", docAttr);
1136
1150
  io.out("Gave the page a new document identity (data-pipeup-doc).");
1137
1151
  }
1138
- const { id } = await K(docAttr).catch(() => {
1152
+ const { id } = await J(docAttr).catch(() => {
1139
1153
  throw new UsageError("data-pipeup-doc in the page isn't a valid document identity");
1140
1154
  });
1141
1155
  const from = typeof flags.get("from") === "string" ? flags.get("from") : null;
@@ -1205,7 +1219,7 @@ async function addressOf(file, io) {
1205
1219
  const a = parseShare(readAttribute(html, "data-pipeup-share"), true);
1206
1220
  if (a.kind === "off") throw new UsageError(`${file}: ${a.reason}`);
1207
1221
  const docAttr = readAttribute(html, "data-pipeup-doc");
1208
- const doc = docAttr ? (await K(docAttr).catch(() => null))?.id : null;
1222
+ const doc = docAttr ? (await J(docAttr).catch(() => null))?.id : null;
1209
1223
  if (!doc) throw new UsageError(`${file} has no valid data-pipeup-doc`);
1210
1224
  return { html, a, l: ladder(doc, a.key) };
1211
1225
  }