@pipeup/share 0.8.2 → 0.9.1

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/share.esm.js CHANGED
@@ -1 +1 @@
1
- var f=n=>new TextEncoder().encode(n),X=n=>new TextDecoder().decode(n);function v(n){let t="";for(let e=0;e<n.length;e+=32768)t+=String.fromCharCode(...n.subarray(e,e+32768));return btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function y(n){let t=n.replace(/-/g,"+").replace(/_/g,"/"),e=atob(t+"=".repeat((4-t.length%4)%4));return Uint8Array.from(e,r=>r.charCodeAt(0))}function S(n){let t="";for(let e=0;e<n.length;e+=32768)t+=String.fromCharCode(...n.subarray(e,e+32768));return btoa(t)}function Y(n){return Uint8Array.from(atob(n),t=>t.charCodeAt(0))}var P=n=>crypto.getRandomValues(new Uint8Array(n));async function L(n){return new Uint8Array(await crypto.subtle.digest("SHA-256",n))}var Ae=/^([A-Za-z0-9_-]{16}):([A-Za-z0-9_-]{43})$/;function V(n,t=document){let e=Ae.exec(t.documentElement.getAttribute("data-pipeup-doc")?.trim()??"");return e&&e[1]===n?y(e[2]):null}var xe=n=>f(`pipeup/v1/doc:${n}`);async function de(n,t,e,r){let i=await crypto.subtle.importKey("raw",n,"HKDF",!1,["deriveBits"]);return crypto.subtle.deriveBits({name:"HKDF",hash:"SHA-256",salt:xe(t),info:f(e)},i,r)}function W(n,t){return{docId:n,key:async e=>crypto.subtle.importKey("raw",await de(t,n,`pipeup/v1/${e}/key`,256),"AES-GCM",!1,["encrypt","decrypt"]),addr:async e=>v(new Uint8Array(await de(t,n,`pipeup/v1/${e}/address`,128))),aad:e=>`pipeup/v1/${e}:${n}`}}var Se=1e6,Pe=1e3;async function ce(n,t,e=1/0){let r=new Blob([n]).stream().pipeThrough(t).getReader(),i=[],o=0;for(;;){let{done:d,value:c}=await r.read();if(d)break;if(o+=c.length,o>e)throw r.cancel(),new Error("too large");i.push(c)}let s=new Uint8Array(o),a=0;for(let d of i)s.set(d,a),a+=d.length;return s}var A=(n,t,e)=>D(n,t,{pipeup:1,doc:n.docId,sealed:!1,ops:e});async function D(n,t,e){let r=f(JSON.stringify(e)),i=P(12),o=await crypto.subtle.encrypt({name:"AES-GCM",iv:i,additionalData:f(n.aad(t))},await n.key(t),await ce(r,new CompressionStream("deflate-raw"))),s=new Uint8Array(13+o.byteLength);return s[0]=1,s.set(i,1),s.set(new Uint8Array(o),13),s}async function I(n,t,e){try{if(e.length<29||e[0]!==1)return null;let r=await crypto.subtle.decrypt({name:"AES-GCM",iv:e.slice(1,13),additionalData:f(n.aad(t))},await n.key(t),e.slice(13));return JSON.parse(X(await ce(new Uint8Array(r),new DecompressionStream("deflate-raw"),Se)))}catch{return null}}function C(n,t){let e=t;if(e?.pipeup!==1||e.doc!==n.docId||!Array.isArray(e.ops)||e.ops.length>Pe)return null;let r=0;for(let i of e.ops){let o=i?.body?.v;typeof o=="number"&&o!==1&&r++}return{ops:e.ops,newer:r}}async function Q(n,t,e){return C(n,await I(n,t,e))}var ee=n=>`pu1.${v(n)}`,te=n=>{if(!/^pu1\.[A-Za-z0-9_-]+$/.test(n))return null;try{return y(n.slice(4))}catch{return null}};async function ne(n,t={}){let e=new Map,r={get:async i=>e.get(i),set:async(i,o)=>void e.set(i,o),lasting:!1};if(t.memory||typeof indexedDB>"u")return r;try{let i=await new Promise((s,a)=>{let d=setTimeout(()=>a(new Error("timed out")),4e3),c=indexedDB.open(`pipeup-addon-${n}`,1);c.onupgradeneeded=()=>c.result.createObjectStore("kv"),c.onsuccess=()=>{clearTimeout(d),s(c.result)},c.onerror=c.onblocked=()=>{clearTimeout(d),a(c.error??new Error("blocked"))}}),o=(s,a)=>new Promise((d,c)=>{let m=a(i.transaction("kv",s).objectStore("kv"));m.onsuccess=()=>d(m.result),m.onerror=()=>c(m.error)});return{get:s=>o("readonly",a=>a.get(s)),set:async(s,a)=>void await o("readwrite",d=>d.put(a,s)),lasting:!0}}catch{return r}}var h=class extends Error{constructor(e,r=!1){super(`try again in ${e} s`);this.seconds=e;this.limit=r;this.name="RetryAfter"}};var Te=100,le=5e3,Oe=5e3,Be=3e5,Ue=3600,E=class{constructor(t){this.o=t}state="idle";lastOk=0;known=new Set;outbox=new Map;rejected=new Set;inbound=[];inboundTimer=0;sendTimer=0;lastSend=0;backoff=0;off=null;listeners=new Set;stopped=!1;get waiting(){return this.outbox.size}pending(){return[...this.outbox.values()]}onState(t){return this.listeners.add(t),()=>this.listeners.delete(t)}emit(t){t&&(this.state=t);for(let e of[...this.listeners])e()}async start(){let{document:t,transport:e,signal:r}=this.o;this.off=t.onChange((o,s,a)=>{if(a===this.o.id)return;let d=!1;for(let c of s)this.want(c)&&(d=this.outbox.set(c.body.id,c).size>0||d);d&&this.schedule(),this.emit()}),r.addEventListener("abort",()=>this.stop(),{once:!0}),await e.start(o=>this.deliver(o));let i=await e.remoteIds?.();if(i)for(let o of i)this.known.add(o);this.rescan()}stop(){this.stopped||(this.stopped=!0,this.off?.(),clearTimeout(this.inboundTimer),clearTimeout(this.sendTimer),this.o.transport.stop())}want(t){return!this.known.has(t.body.id)&&!this.rejected.has(t.body.id)&&this.o.sendable(t)}rescan(){this.outbox.clear();for(let t of this.o.document.ops())this.want(t)&&this.outbox.set(t.body.id,t);this.schedule(),this.emit()}deliver(t){this.inbound.push(...t),this.inboundTimer||(this.inboundTimer=setTimeout(()=>void this.drain(),Te))}async drain(){this.inboundTimer=0;let t=this.inbound.splice(0),e=t.map(i=>i?.body?.id).filter(i=>typeof i=="string");for(let i=0;i<t.length;i+=le)try{await this.o.merge(t.slice(i,i+le))}catch(o){o?.name!=="UnsavedChangeError"&&globalThis.reportError?.(o)}let r=new Set(this.o.document.ops().map(i=>i.body.id));for(let i of e)r.has(i)?(this.known.add(i),this.outbox.delete(i)):this.rejected.add(i);this.lastOk=Date.now(),this.emit()}schedule(t=this.o.delay??0){if(this.stopped||this.sendTimer||this.outbox.size===0)return;let e=typeof this.o.gap=="function"?this.o.gap():this.o.gap??0,r=Math.max(t,this.lastSend+e-Date.now(),this.backoff);this.sendTimer=setTimeout(()=>void this.send(),r)}async send(){if(this.sendTimer=0,this.stopped||this.o.signal.aborted||this.outbox.size===0)return;let t=[...this.outbox.values()].slice(0,this.o.batch??500);this.emit("sending");try{await this.o.transport.send(t);for(let e of t)this.known.add(e.body.id),this.outbox.delete(e.body.id);this.lastSend=Date.now(),this.lastOk=this.lastSend,this.backoff=0,this.emit("idle")}catch(e){e instanceof h?(this.backoff=Math.min(e.seconds,Ue)*1e3*(1+Math.random()*.2),this.emit("limited")):(this.backoff=Math.min(Be,this.backoff?this.backoff*2:Oe),this.emit("offline"))}this.schedule()}};var at=2n**256n-2n**32n-977n;var Ee="sharing isn't set up for this page",M="data-pipeup-share isn't a sharing address",Me=/^(localhost|127\.0\.0\.1|\[::1\])$/,pe=/^[A-Za-z0-9_-]{43}$/,T=n=>({kind:"off",reason:n});function he(n,t=!1){let e=n?.trim();if(!e)return T(Ee);let r;try{r=new URL(e)}catch{return T(M)}if(r.protocol!=="https:"&&!(t&&r.protocol==="http:"&&Me.test(r.hostname)))return T(M);let i=r.origin+r.pathname,o=r.hash.slice(1);if(o.startsWith("pm1.")){let[a,d,...c]=o.slice(4).split(".");return!pe.test(a??"")||c.length||d!==void 0&&!/^[A-Za-z0-9_-]+$/.test(d)||r.search||!/\/m\/[A-Za-z0-9_-]{22,64}$/.test(i)?T(M):{kind:"mailbox",mailbox:i,key:y(a),...d?{token:d}:{}}}let s=/^\?([A-Za-z0-9_-]{8,64})$/.exec(r.search)?.[1];return!s||!pe.test(o)?T(M):{kind:"privatebin",base:i,paste:s,key:y(o)}}var g=class extends Error{constructor(e){super(e);this.kind=e;this.name="Problem"}},ue={Accept:"application/json"},N=(n,t,e)=>n(t,{headers:ue,credentials:"omit",signal:e}),O=n=>({method:"POST",headers:ue,credentials:"omit",body:JSON.stringify(n)}),fe=n=>{let t={403:"closed",404:"gone",507:"full"}[n];return t&&new g(t)};async function B(n){let t=await n.text(),e=t.length<1e7&&JSON.parse(t);if(!e||typeof e!="object")throw new Error("the answer was not usable");return[e,t.length]}function $(n,t=9e5){let e=[],r=0;for(let i of n)r+=JSON.stringify(i).length,(!e.length||r>t||e.at(-1).length>=500)&&(e.push([]),r=JSON.stringify(i).length),e.at(-1).push(i);return e}var U=(n,t)=>new Promise(e=>{let r=setTimeout(e,n);t?.addEventListener("abort",()=>{clearTimeout(r),e()},{once:!0})}),z=(n,t=10)=>{let e=Number(n.headers.get("Retry-After"));return e>0?Math.min(e,3600):t},_=n=>n.map(t=>t?.body?.id).filter(t=>typeof t=="string");var $e=524288,Re=1e3,Le=async n=>v(await L(f(n))).slice(0,22),j=class{constructor(t,e,r,i){this.a=t;this.l=e;this.f=r;this.signal=i}ids=new Set;expires=null;moved=!1;big=!1;cursor="";seen=new Set;memo=null;async read(){let t=[],e=0;for(let r=0;r<Re;){let i=`${this.a.mailbox}/ops${this.cursor?`?since=${encodeURIComponent(this.cursor)}`:""}`,o=await N(this.f,i,this.signal);if(o.status===404)throw new g("gone");if(o.status===409&&e++<2){this.cursor="";continue}if(!o.ok)throw new Error(`HTTP ${o.status}`);r++;let[s]=await B(o);for(let a of Array.isArray(s.batches)?s.batches:[]){if(typeof a?.id!="string"||typeof a.ct!="string"||this.seen.has(a.id))continue;this.seen.add(a.id);let d=te(a.ct),c=d&&await Q(this.l,"share",d);if(c){t.push(c);for(let m of _(c.ops))this.ids.add(m)}}if(typeof s.next=="string"&&(this.cursor=s.next),this.expires=typeof s.expires=="string"&&Date.parse(s.expires)||null,s.more!==!0)break}return t}async req(t){let e=t.map(o=>o.body.id).join();if(this.memo?.key!==e){let o=ee(await A(this.l,"share",t));this.memo={key:e,ct:o,id:await Le(o)}}let{ct:r,id:i}=this.memo;return[`${this.a.mailbox}/ops`,O({id:i,ct:r,token:this.a.token})]}async post(t){for(let e of $(t))await this.one(e)}async one(t){let[e,r]=await this.req(t),i=async()=>{let d=t.length>>1;await this.one(t.slice(0,d)),await this.one(t.slice(d))};if(r.body.length>$e&&t.length>1)return i();let o=await this.f(e,{...r,signal:this.signal}),s=o.status;if(s===200||s===201||s===400)return;if(s===413&&t.length>1)return i();let a=fe(s);if(a)throw a;if(s===429){let[d]=await B(o).catch(()=>[{}]),c=Number(d.retryAfter);throw new h(o.headers.get("Retry-After")?z(o):c>0?Math.min(c,3600):10)}throw new Error(`HTTP ${s}`)}};var H=class{constructor(t,e){this.me=t;this.held=new Set(e?.held),this.kept=new Set(e?.kept),this.recv=new Set(e?.recv),this.send=e?.send??!0,this.noted=e?.noted??!1,this.gen=e?.gen??null,this.init=e?.init??!1}held;kept;recv;send;noted;gen;init;hold(t){if(!this.init){this.init=!0;for(let{body:e}of t)e.author===this.me&&this.held.add(e.id)}}sendable(t){let e=t.body;if(this.recv.has(e.id))return!0;if(e.author!==this.me||this.held.has(e.id)||this.kept.has(e.id))return!1;let r=[e.target,e.thread].find(i=>i&&(this.held.has(i)||this.kept.has(i)));if(r)(this.held.has(r)?this.held:this.kept).add(e.id);else if(!this.send)this.kept.add(e.id);else return(e.kind==="create"||e.kind==="reply")&&(this.noted=!0),!0;return!1}decide(t){if(!t)for(let e of this.held)this.kept.add(e);this.held.clear()}};var De=256e3,Ie=16,Ce=/^[A-Za-z0-9_-]{8,64}$/,me=()=>[S(P(16)),S(P(8)),1e5,256,128,"aes","gcm","none"],Ne=(n,t)=>({v:2,adata:me(),ct:S(t),pasteid:n,parentid:n});async function q(n){if(n.status===429)throw new h(z(n));if(!n.ok)throw new Error(`HTTP ${n.status}`);let[t]=await B(n);if(t.status===0)return t;let e=Number(/\d+/.exec(String(t.message??""))?.[0]);throw new h(e>=1&&e<=3600?e:30,!0)}async function ze(n,t,e,r="never",i){let o=S(await A(e,"share",[])),s=await q(await n(t,{...O({v:2,adata:[me(),"plaintext",1,0],ct:o,meta:{expire:r}}),signal:i}));if(typeof s.id!="string"||typeof s.deletetoken!="string")throw new Error("the answer had no paste id");return{id:s.id,deleteToken:s.deletetoken}}async function je(n,t,e,r){return n(t,O({pasteid:e,deletetoken:r}))}async function He(n,t,e,r){let i=await N(n,`${t}?${e}`,r);if(i.status===404)return null;if(!i.ok)throw new Error(`HTTP ${i.status}`);let[o,s]=await B(i);if(o.status!==0)return null;let a=o.meta?.time_to_live;return{j:o,size:s,ttl:typeof a=="number"&&a>0?a*1e3:null}}var F=class{constructor(t,e,r,i,o,s=()=>{}){this.a=t;this.l=e;this.f=r;this.signal=i;this.onGen=s;this.head=o||t.paste,this.trail.push(t.paste)}ids=new Set;expires=null;moved=!1;big=!1;head;trail=[];seen=new Map;async scan(t,e){let r;for(let i of Array.isArray(t)?t:[]){if(typeof i?.id!="string"||typeof i.ct!="string")continue;let o=this.seen.get(i.id);if(o===void 0){o=null;let s=null;try{i.ct.length<14e5&&(s=Y(i.ct))}catch{}let a=s&&await I(this.l,"share",s),d=a?.next,c=typeof d=="string"?null:C(this.l,a);if(typeof d=="string"&&Ce.test(d))o=d;else if(c){e.push(c);for(let m of _(c.ops))this.ids.add(m)}this.seen.set(i.id,o)}r??=o??void 0}return r}async read(){let t=[],e=this.head,r=!1,i=!1;for(let o=0;;){let s=await He(this.f,this.a.base,e,this.signal);if(!s){if(i)break;if(!r&&e!==this.a.paste){r=!0,e=this.a.paste;continue}throw new g("gone")}i=!0,e!==this.head&&(this.head=e,this.trail.push(e),this.ids.clear(),this.moved=!0,this.onGen(e));let a=s.j.comments,d=await this.scan(a,t);this.expires=s.ttl&&Date.now()+s.ttl;let c=(Array.isArray(a)?a[0]?.ct?.length:0)??0;if(this.big=!d&&s.size>De&&s.size>2*c,!d||++o>=Ie)break;e=d}return t}ask(t,e){return[this.a.base,O(Ne(t,e))]}async req(t){return this.ask(this.head,await A(this.l,"share",t))}go(t,e){return this.f(t,{...e,signal:this.signal})}async post(t){for(let e of $(t))await q(await this.go(...await this.req(e)))}async roll(t){let e=async s=>{for(let a=0;;a++)try{return await s()}catch(d){if(!(d instanceof h)||a>5||this.signal?.aborted)throw d;await U(d.seconds*1e3*(1+Math.random()*.2),this.signal)}},r=this.head,i=await e(()=>ze(this.f,this.a.base,this.l,"never",this.signal));for(let s of $(t))await e(async()=>q(await this.go(...this.ask(i.id,await A(this.l,"share",s)))));await e(async()=>q(await this.go(...this.ask(r,await D(this.l,"share",{next:i.id})))));let o=await this.read();return this.head!==i.id&&await je(this.f,this.a.base,i.id,i.deleteToken).catch(()=>{}),o}};function qe(n,t,e,r=Math.random()){let i=t?3e5:n<6e5?25e3+r*1e4:n<18e5?12e4:3e5;return Math.min(3e5,i*2**e)}var K=class{constructor(t,e){this.b=t;this.o=e}id="share";problem=null;offline=!1;newer=0;deliver=()=>{};active=Date.now();errors=0;ok=!1;timer;busy=null;again=!1;limit=0;rolling=!1;ready=null;stopped=!1;off=[];async start(t){this.deliver=t;let e=(i,o,s)=>{i&&(i.addEventListener(o,s),this.off.push(()=>i.removeEventListener(o,s)))},r=globalThis;r.addEventListener&&(e(globalThis,"focus",()=>void this.poll()),e(globalThis,"online",()=>void this.poll()),e(globalThis,"pagehide",()=>this.flush()),e(r.document,"visibilitychange",()=>r.document?.visibilityState==="visible"&&void this.poll())),await this.poll()}stop(){this.stopped=!0,clearTimeout(this.timer);for(let t of this.off.splice(0))t()}async remoteIds(){return this.ok?this.b.ids:null}poll(){if(this.busy)return this.again=!0,this.busy;let t=async()=>{do this.again=!1,await this.read();while(this.again&&!this.stopped)};return this.busy=t().finally(()=>this.busy=null)}bump(){this.active=Date.now()}async read(){clearTimeout(this.timer);try{let t=await this.b.read();this.offline=!1,this.errors=0,this.ok=!0,this.newer+=t.reduce((r,i)=>r+i.newer,0);let e=t.flatMap(r=>r.ops);if(e.length&&(this.active=Date.now(),this.deliver(e)),this.b.moved){this.b.moved=!1;let r=this.o.allowed().filter(i=>!this.b.ids.has(i.body.id));r.length&&await this.b.post(r).catch(()=>{})}this.b.big&&!this.rolling&&this.roll()}catch(t){t instanceof g?this.problem=t.kind:(this.offline=!0,this.errors++)}if(this.o.changed(),!this.stopped&&this.problem!=="gone"){let t=globalThis.document?.visibilityState==="hidden";this.timer=setTimeout(()=>void this.poll(),qe(Date.now()-this.active,t,this.errors))}}lock(t,e=0){let r=this.o.lock,i=globalThis.navigator?.locks;return r?i?new Promise((o,s)=>{i.request(r,{signal:this.o.signal},async()=>{try{o(await t())}catch(a){s(a)}await U(e,this.o.signal)}).catch(s)}):U(Math.random()*5e3,this.o.signal).then(t):t()}get gap(){return Math.max(this.o.gap,this.limit)}async guarded(t){try{await this.lock(t,this.gap),this.offline=!1}catch(e){throw e instanceof h?(e.limit&&(this.limit=Math.max(this.limit,e.seconds*1e3)),e):e instanceof g?(this.problem=e.kind,this.o.changed(),new h(3600)):(this.offline=!0,this.o.changed(),e)}}async send(t){if(this.problem)throw new h(3600);this.bump(),await this.guarded(async()=>{await this.poll();let e=t.filter(r=>!this.b.ids.has(r.body.id));if(e.length){await this.b.post(e);for(let r of e)this.b.ids.add(r.body.id)}})}async prepare(t){try{this.ready=t.length&&JSON.stringify(t).length<4e4?await this.b.req(t):null}catch{this.ready=null}}flush(){let t=this.ready;this.ready=null,!(!t||this.problem||typeof t[1].body!="string"||t[1].body.length>64e3)&&(this.o.fetch??fetch)(t[0],{...t[1],keepalive:!0}).catch(()=>{})}async roll(){this.rolling=!0;try{await U(Math.random()*3e4,this.o.signal),await this.guarded(async()=>{if(await this.poll(),!this.b.big||!this.b.roll)return;let e=(await this.b.roll(this.o.allowed())).flatMap(r=>r.ops);e.length&&this.deliver(e)})}catch{}finally{this.rolling=!1}}};var Fe="Comments here are shared with everyone who has this page.",Ke=7*864e5,ge=["M12 16V4M7 9l5-5 5 5M5 20h14"],Ge=["M7 11V8a5 5 0 0 1 10 0v3M6 11h12v9H6z"];function ye(n={}){return{id:"share",api:1,version:"0.4.1",needs:["sync","menu","notify","note"],network:{when:"page-configured",to:["page"],says:"Sends the comments you choose to share, sealed so only people with this page can read them, to the sharing service the page names. That service sees when and how much is sent, and your network address."},async setup(t){let e=t.document,r=he(n.share??document.documentElement.getAttribute("data-pipeup-share"),!0);if(r.kind==="off")return t.off(r.reason);if(!V(e.id))return t.off("needs a document identity");let i=W(e.id,r.key),o=await ne("share",{memory:t.ephemeral}),s=await o.get(`doc:${e.id}`),a=new H(e.me,s);a.hold(e.ops());let d=Promise.resolve(),c=()=>{d=d.then(()=>o.set(`doc:${e.id}`,{...a})).catch(()=>{})};c();let m={gone:"The shared copy is gone",closed:"This page can't send to the shared copy; ask the author for the current file",full:"The shared copy is full; the author can start it again"},re=new Set,ie=(l,u)=>re.has(l)||(re.add(l),t.notify(u)),x=()=>{for(let l of R)l.update();t.setStatus({text:ae()}),t.setComposerNote(a.send&&!a.noted&&p.problem!=="gone"?Fe:null),p.newer&&ie("newer",`${p.newer} comments come from a newer version of Pipeup; this page can't show them yet.`),p.problem&&ie(p.problem,m[p.problem]+(p.problem==="gone"?". Your comments stay on this machine.":"."))},oe=(l,u)=>fetch(l,u),se=r.kind==="mailbox"?new j(r,i,oe,t.signal):new F(r,i,oe,t.signal,a.gen,l=>{a.gen=l,c()}),p=new K(se,{signal:t.signal,gap:1e4,lock:`pipeup-share:${e.id}`,allowed:()=>e.ops().filter(l=>a.sendable(l)),changed:x}),b=new E({id:"share",document:e,merge:async l=>{let u=await t.merge(l),k=new Set(e.ops().map(w=>w.body.id));for(let w of _(l))k.has(w)&&a.recv.add(w);return c(),u},transport:p,sendable:l=>{let u=a.sendable(l);return a.noted!==s?.noted&&c(),u},signal:t.signal,delay:2e3,gap:()=>p.gap}),G;b.onState(()=>{x(),clearTimeout(G),G=setTimeout(()=>void p.prepare(b.pending()),1e3)});let be=new URL(r.kind==="mailbox"?r.mailbox:r.base).host,ae=()=>{let l=b.waiting;return p.problem?m[p.problem]:a.send?p.offline||b.state==="offline"?"Shared \xB7 offline, sends when back":l?`Shared \xB7 ${l} change${l===1?"":"s"} waiting`:"Shared \xB7 up to date":"Shared \xB7 not sending your comments"},we=()=>{let l=se.expires;return p.problem==="gone"?"Your comments stay on this machine. The author can start sharing again.":[`Your comments are encrypted and sent to ${be} so others with this page see them. The service can't read them. People who already have your comments, by file or live, could pass them on.`,t.ephemeral&&"This browser can't keep comments; the shared copy keeps the ones you send.",!o.lasting&&"This browser won't remember this choice.",l&&l-Date.now()<Ke&&`The shared copy expires on ${new Date(l).toLocaleDateString("en-GB",{day:"numeric",month:"long"})}.`].filter(Boolean).join(" ")},R=[],J=(l,u,k,w,ve,ke)=>R[R.push(t.addMenuItem({id:l,icon:u,label:k,hint:w,select:ve,checked:ke}))-1],Z=e.ops().filter(l=>a.held.has(l.body.id)&&(l.body.kind==="create"||l.body.kind==="reply")).length;if(J("send",ge,()=>a.send||p.problem?ae():"Send my comments",we,()=>{a.send=!a.send,c(),b.rescan(),x()},()=>a.send),Z){let l=o.lasting?"":" This browser won't remember this choice.",u=k=>()=>{a.decide(k),c();for(let w of R.splice(1))w.remove();b.rescan(),x()};J("share-earlier",ge,()=>`Share my ${Z} earlier comment${Z===1?"":"s"}`,()=>`Send the comments you wrote before this page was shared.${l}`,u(!0)),J("keep-earlier",Ge,()=>"Keep them on this machine",()=>`Never send the comments you wrote before this page was shared.${l}`,u(!1))}return x(),b.start().then(x,l=>globalThis.reportError?.(l)),e.onChange((l,u,k)=>{k==="local"&&u.length&&p.bump()}),()=>{clearTimeout(G),b.stop()}}}}export{ye as createAddon,ye as default};
1
+ var S=(n,t)=>t?t.getAttribute(n):globalThis.Pipeup?.setting?.(n)??globalThis.document?.documentElement.getAttribute(n)??null;var m=n=>new TextEncoder().encode(n),W=n=>new TextDecoder().decode(n);function k(n){let t="";for(let e=0;e<n.length;e+=32768)t+=String.fromCharCode(...n.subarray(e,e+32768));return btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function w(n){let t=n.replace(/-/g,"+").replace(/_/g,"/"),e=atob(t+"=".repeat((4-t.length%4)%4));return Uint8Array.from(e,r=>r.charCodeAt(0))}function P(n){let t="";for(let e=0;e<n.length;e+=32768)t+=String.fromCharCode(...n.subarray(e,e+32768));return btoa(t)}function V(n){return Uint8Array.from(atob(n),t=>t.charCodeAt(0))}var T=n=>crypto.getRandomValues(new Uint8Array(n));async function D(n){return new Uint8Array(await crypto.subtle.digest("SHA-256",n))}var Te=/^([A-Za-z0-9_-]{16}):([A-Za-z0-9_-]{43})$/;function Q(n,t=document){let e=Te.exec((t===globalThis.document?S("data-pipeup-doc"):t.documentElement.getAttribute("data-pipeup-doc"))?.trim()??"");return e&&e[1]===n?w(e[2]):null}var Oe=n=>m(`pipeup/v1/doc:${n}`);async function pe(n,t,e,r){let i=await crypto.subtle.importKey("raw",n,"HKDF",!1,["deriveBits"]);return crypto.subtle.deriveBits({name:"HKDF",hash:"SHA-256",salt:Oe(t),info:m(e)},i,r)}function ee(n,t){return{docId:n,key:async e=>crypto.subtle.importKey("raw",await pe(t,n,`pipeup/v1/${e}/key`,256),"AES-GCM",!1,["encrypt","decrypt"]),addr:async e=>k(new Uint8Array(await pe(t,n,`pipeup/v1/${e}/address`,128))),aad:e=>`pipeup/v1/${e}:${n}`}}var Be=1e6,Ee=1e3;async function he(n,t,e=1/0){let r=new Blob([n]).stream().pipeThrough(t).getReader(),i=[],o=0;for(;;){let{done:d,value:l}=await r.read();if(d)break;if(o+=l.length,o>e)throw r.cancel(),new Error("too large");i.push(l)}let s=new Uint8Array(o),a=0;for(let d of i)s.set(d,a),a+=d.length;return s}var A=(n,t,e)=>L(n,t,{pipeup:1,doc:n.docId,sealed:!1,ops:e});async function L(n,t,e){let r=m(JSON.stringify(e)),i=T(12),o=await crypto.subtle.encrypt({name:"AES-GCM",iv:i,additionalData:m(n.aad(t))},await n.key(t),await he(r,new CompressionStream("deflate-raw"))),s=new Uint8Array(13+o.byteLength);return s[0]=1,s.set(i,1),s.set(new Uint8Array(o),13),s}async function C(n,t,e){try{if(e.length<29||e[0]!==1)return null;let r=await crypto.subtle.decrypt({name:"AES-GCM",iv:e.slice(1,13),additionalData:m(n.aad(t))},await n.key(t),e.slice(13));return JSON.parse(W(await he(new Uint8Array(r),new DecompressionStream("deflate-raw"),Be)))}catch{return null}}function N(n,t){let e=t;if(e?.pipeup!==1||e.doc!==n.docId||!Array.isArray(e.ops)||e.ops.length>Ee)return null;let r=0;for(let i of e.ops){let o=i?.body?.v;typeof o=="number"&&o!==1&&r++}return{ops:e.ops,newer:r}}async function te(n,t,e){return N(n,await C(n,t,e))}var ne=n=>`pu1.${k(n)}`,re=n=>{if(!/^pu1\.[A-Za-z0-9_-]+$/.test(n))return null;try{return w(n.slice(4))}catch{return null}};async function ie(n,t={}){let e=new Map,r={get:async i=>e.get(i),set:async(i,o)=>void e.set(i,o),lasting:!1};if(t.memory||typeof indexedDB>"u")return r;try{let i=await new Promise((s,a)=>{let d=setTimeout(()=>a(new Error("timed out")),4e3),l=indexedDB.open(`pipeup-addon-${n}`,1);l.onupgradeneeded=()=>l.result.createObjectStore("kv"),l.onsuccess=()=>{clearTimeout(d),s(l.result)},l.onerror=l.onblocked=()=>{clearTimeout(d),a(l.error??new Error("blocked"))}}),o=(s,a)=>new Promise((d,l)=>{let f=a(i.transaction("kv",s).objectStore("kv"));f.onsuccess=()=>d(f.result),f.onerror=()=>l(f.error)});return{get:s=>o("readonly",a=>a.get(s)),set:async(s,a)=>void await o("readwrite",d=>d.put(a,s)),lasting:!0}}catch{return r}}var u=class extends Error{constructor(e,r=!1){super(`try again in ${e} s`);this.seconds=e;this.limit=r;this.name="RetryAfter"}};var Ue=100,ue=5e3,_e=5e3,Me=3e5,Re=3600,M=class{constructor(t){this.o=t}state="idle";lastOk=0;known=new Set;outbox=new Map;rejected=new Set;inbound=[];inboundTimer=0;sendTimer=0;lastSend=0;backoff=0;off=null;listeners=new Set;stopped=!1;get waiting(){return this.outbox.size}pending(){return[...this.outbox.values()]}onState(t){return this.listeners.add(t),()=>this.listeners.delete(t)}emit(t){t&&(this.state=t);for(let e of[...this.listeners])e()}async start(){let{document:t,transport:e,signal:r}=this.o;this.off=t.onChange((o,s,a)=>{if(a===this.o.id)return;let d=!1;for(let l of s)this.want(l)&&(d=this.outbox.set(l.body.id,l).size>0||d);d&&this.schedule(),this.emit()}),r.addEventListener("abort",()=>this.stop(),{once:!0}),await e.start(o=>this.deliver(o));let i=await e.remoteIds?.();if(i)for(let o of i)this.known.add(o);this.rescan()}stop(){this.stopped||(this.stopped=!0,this.off?.(),clearTimeout(this.inboundTimer),clearTimeout(this.sendTimer),this.o.transport.stop())}want(t){return!this.known.has(t.body.id)&&!this.rejected.has(t.body.id)&&this.o.sendable(t)}rescan(){this.outbox.clear();for(let t of this.o.document.ops())this.want(t)&&this.outbox.set(t.body.id,t);this.schedule(),this.emit()}deliver(t){this.inbound.push(...t),this.inboundTimer||(this.inboundTimer=setTimeout(()=>void this.drain(),Ue))}async drain(){this.inboundTimer=0;let t=this.inbound.splice(0),e=t.map(i=>i?.body?.id).filter(i=>typeof i=="string");for(let i=0;i<t.length;i+=ue)try{await this.o.merge(t.slice(i,i+ue))}catch(o){o?.name!=="UnsavedChangeError"&&globalThis.reportError?.(o)}let r=new Set(this.o.document.ops().map(i=>i.body.id));for(let i of e)r.has(i)?(this.known.add(i),this.outbox.delete(i)):this.rejected.add(i);this.lastOk=Date.now(),this.emit()}schedule(t=this.o.delay??0){if(this.stopped||this.sendTimer||this.outbox.size===0)return;let e=typeof this.o.gap=="function"?this.o.gap():this.o.gap??0,r=Math.max(t,this.lastSend+e-Date.now(),this.backoff);this.sendTimer=setTimeout(()=>void this.send(),r)}async send(){if(this.sendTimer=0,this.stopped||this.o.signal.aborted||this.outbox.size===0)return;let t=[...this.outbox.values()].slice(0,this.o.batch??500);this.emit("sending");try{await this.o.transport.send(t);for(let e of t)this.known.add(e.body.id),this.outbox.delete(e.body.id);this.lastSend=Date.now(),this.lastOk=this.lastSend,this.backoff=0,this.emit("idle")}catch(e){e instanceof u?(this.backoff=Math.min(e.seconds,Re)*1e3*(1+Math.random()*.2),this.emit("limited")):(this.backoff=Math.min(Me,this.backoff?this.backoff*2:_e),this.emit("offline"))}this.schedule()}};var gt=2n**256n-2n**32n-977n;var Ie="sharing isn't set up for this page",R="data-pipeup-share isn't a sharing address",De=/^(localhost|127\.0\.0\.1|\[::1\])$/,fe=/^[A-Za-z0-9_-]{43}$/,O=n=>({kind:"off",reason:n});function me(n,t=!1){let e=n?.trim();if(!e)return O(Ie);let r;try{r=new URL(e)}catch{return O(R)}if(r.protocol!=="https:"&&!(t&&r.protocol==="http:"&&De.test(r.hostname)))return O(R);let i=r.origin+r.pathname,o=r.hash.slice(1);if(o.startsWith("pm1.")){let[a,d,...l]=o.slice(4).split(".");return!fe.test(a??"")||l.length||d!==void 0&&!/^[A-Za-z0-9_-]+$/.test(d)||r.search||!/\/m\/[A-Za-z0-9_-]{22,64}$/.test(i)?O(R):{kind:"mailbox",mailbox:i,key:w(a),...d?{token:d}:{}}}let s=/^\?([A-Za-z0-9_-]{8,64})$/.exec(r.search)?.[1];return!s||!fe.test(o)?O(R):{kind:"privatebin",base:i,paste:s,key:w(o)}}var b=class extends Error{constructor(e){super(e);this.kind=e;this.name="Problem"}},ge={Accept:"application/json"},z=(n,t,e)=>n(t,{headers:ge,credentials:"omit",signal:e}),B=n=>({method:"POST",headers:ge,credentials:"omit",body:JSON.stringify(n)}),ye=n=>{let t={403:"closed",404:"gone",507:"full"}[n];return t&&new b(t)};async function E(n){let t=await n.text(),e=t.length<1e7&&JSON.parse(t);if(!e||typeof e!="object")throw new Error("the answer was not usable");return[e,t.length]}function $(n,t=9e5){let e=[],r=0;for(let i of n)r+=JSON.stringify(i).length,(!e.length||r>t||e.at(-1).length>=500)&&(e.push([]),r=JSON.stringify(i).length),e.at(-1).push(i);return e}var U=(n,t)=>new Promise(e=>{let r=setTimeout(e,n);t?.addEventListener("abort",()=>{clearTimeout(r),e()},{once:!0})}),H=(n,t=10)=>{let e=Number(n.headers.get("Retry-After"));return e>0?Math.min(e,3600):t},_=n=>n.map(t=>t?.body?.id).filter(t=>typeof t=="string");var Le=524288,Ce=1e3,Ne=async n=>k(await D(m(n))).slice(0,22),j=class{constructor(t,e,r,i){this.a=t;this.l=e;this.f=r;this.signal=i}ids=new Set;expires=null;moved=!1;big=!1;cursor="";seen=new Set;memo=null;async read(){let t=[],e=0;for(let r=0;r<Ce;){let i=`${this.a.mailbox}/ops${this.cursor?`?since=${encodeURIComponent(this.cursor)}`:""}`,o=await z(this.f,i,this.signal);if(o.status===404)throw new b("gone");if(o.status===409&&e++<2){this.cursor="";continue}if(!o.ok)throw new Error(`HTTP ${o.status}`);r++;let[s]=await E(o);for(let a of Array.isArray(s.batches)?s.batches:[]){if(typeof a?.id!="string"||typeof a.ct!="string"||this.seen.has(a.id))continue;this.seen.add(a.id);let d=re(a.ct),l=d&&await te(this.l,"share",d);if(l){t.push(l);for(let f of _(l.ops))this.ids.add(f)}}if(typeof s.next=="string"&&(this.cursor=s.next),this.expires=typeof s.expires=="string"&&Date.parse(s.expires)||null,s.more!==!0)break}return t}async req(t){let e=t.map(o=>o.body.id).join();if(this.memo?.key!==e){let o=ne(await A(this.l,"share",t));this.memo={key:e,ct:o,id:await Ne(o)}}let{ct:r,id:i}=this.memo;return[`${this.a.mailbox}/ops`,B({id:i,ct:r,token:this.a.token})]}async post(t){for(let e of $(t))await this.one(e)}async one(t){let[e,r]=await this.req(t),i=async()=>{let d=t.length>>1;await this.one(t.slice(0,d)),await this.one(t.slice(d))};if(r.body.length>Le&&t.length>1)return i();let o=await this.f(e,{...r,signal:this.signal}),s=o.status;if(s===200||s===201||s===400)return;if(s===413&&t.length>1)return i();let a=ye(s);if(a)throw a;if(s===429){let[d]=await E(o).catch(()=>[{}]),l=Number(d.retryAfter);throw new u(o.headers.get("Retry-After")?H(o):l>0?Math.min(l,3600):10)}throw new Error(`HTTP ${s}`)}};var ze=new Set(["reply","addressed","react","unreact"]),be=()=>(S("data-pipeup-agents")??"").split(/[\s,]+/).filter(Boolean),q=class{constructor(t,e,r=()=>[]){this.me=t;this.agents=r;this.held=new Set(e?.held),this.kept=new Set(e?.kept),this.recv=new Set(e?.recv),this.chosen=new Set(e?.chosen),this.follow=new Set(e?.follow),this.legacy=new Set(e?.legacy??(e?.init&&e.chosen===void 0?e.kept:void 0)),this.send=e?.send??!0,this.noted=e?.noted??!1,this.gen=e?.gen??null,this.init=e?.init??!1}held;kept;recv;chosen;follow;legacy;send;noted;gen;init;saved(){let{init:t,held:e,kept:r,recv:i,chosen:o,follow:s,legacy:a,send:d,noted:l,gen:f}=this;return{init:t,held:e,kept:r,recv:i,chosen:o,follow:s,legacy:a,send:d,noted:l,gen:f}}hold(t){if(!this.init){this.init=!0;for(let{body:e}of t)e.author===this.me&&this.held.add(e.id)}}sendable(t){let e=t.body;if(this.recv.has(e.id))return!0;if(ze.has(e.kind)&&this.agents().includes(e.author))return this.send&&![e.target,e.thread].some(i=>i&&(this.held.has(i)||this.kept.has(i)));if(e.author!==this.me||this.held.has(e.id)||this.kept.has(e.id))return!1;let r=[e.target,e.thread].find(i=>i&&(this.held.has(i)||this.kept.has(i)));if(r)(this.held.has(r)?this.held:this.kept).add(e.id),this.follow.add(e.id);else if(!this.send)this.kept.add(e.id);else return(e.kind==="create"||e.kind==="reply")&&(this.noted=!0),!0;return!1}local(t){let e=t.body;return e.author!==this.me||this.recv.has(e.id)||!(this.held.has(e.id)||this.kept.has(e.id))?null:this.follow.has(e.id)?"thread":this.held.has(e.id)?"held":this.chosen.has(e.id)?"chosen":this.legacy.has(e.id)?"unknown":"kept"}decide(t){if(!t)for(let e of this.held)this.kept.add(e),this.chosen.add(e);this.held.clear()}};var He=256e3,je=16,qe=/^[A-Za-z0-9_-]{8,64}$/,we=()=>[P(T(16)),P(T(8)),1e5,256,128,"aes","gcm","none"],Fe=(n,t)=>({v:2,adata:we(),ct:P(t),pasteid:n,parentid:n});async function F(n){if(n.status===429)throw new u(H(n));if(!n.ok)throw new Error(`HTTP ${n.status}`);let[t]=await E(n);if(t.status===0)return t;let e=Number(/\d+/.exec(String(t.message??""))?.[0]);throw new u(e>=1&&e<=3600?e:30,!0)}async function Ke(n,t,e,r="never",i){let o=P(await A(e,"share",[])),s=await F(await n(t,{...B({v:2,adata:[we(),"plaintext",1,0],ct:o,meta:{expire:r}}),signal:i}));if(typeof s.id!="string"||typeof s.deletetoken!="string")throw new Error("the answer had no paste id");return{id:s.id,deleteToken:s.deletetoken}}async function Ge(n,t,e,r){return n(t,B({pasteid:e,deletetoken:r}))}async function Je(n,t,e,r){let i=await z(n,`${t}?${e}`,r);if(i.status===404)return null;if(!i.ok)throw new Error(`HTTP ${i.status}`);let[o,s]=await E(i);if(o.status!==0)return null;let a=o.meta?.time_to_live;return{j:o,size:s,ttl:typeof a=="number"&&a>0?a*1e3:null}}var K=class{constructor(t,e,r,i,o,s=()=>{}){this.a=t;this.l=e;this.f=r;this.signal=i;this.onGen=s;this.head=o||t.paste,this.trail.push(t.paste)}ids=new Set;expires=null;moved=!1;big=!1;head;trail=[];seen=new Map;async scan(t,e){let r;for(let i of Array.isArray(t)?t:[]){if(typeof i?.id!="string"||typeof i.ct!="string")continue;let o=this.seen.get(i.id);if(o===void 0){o=null;let s=null;try{i.ct.length<14e5&&(s=V(i.ct))}catch{}let a=s&&await C(this.l,"share",s),d=a?.next,l=typeof d=="string"?null:N(this.l,a);if(typeof d=="string"&&qe.test(d))o=d;else if(l){e.push(l);for(let f of _(l.ops))this.ids.add(f)}this.seen.set(i.id,o)}r??=o??void 0}return r}async read(){let t=[],e=this.head,r=!1,i=!1;for(let o=0;;){let s=await Je(this.f,this.a.base,e,this.signal);if(!s){if(i)break;if(!r&&e!==this.a.paste){r=!0,e=this.a.paste;continue}throw new b("gone")}i=!0,e!==this.head&&(this.head=e,this.trail.push(e),this.ids.clear(),this.moved=!0,this.onGen(e));let a=s.j.comments,d=await this.scan(a,t);this.expires=s.ttl&&Date.now()+s.ttl;let l=(Array.isArray(a)?a[0]?.ct?.length:0)??0;if(this.big=!d&&s.size>He&&s.size>2*l,!d||++o>=je)break;e=d}return t}ask(t,e){return[this.a.base,B(Fe(t,e))]}async req(t){return this.ask(this.head,await A(this.l,"share",t))}go(t,e){return this.f(t,{...e,signal:this.signal})}async post(t){for(let e of $(t))await F(await this.go(...await this.req(e)))}async roll(t){let e=async s=>{for(let a=0;;a++)try{return await s()}catch(d){if(!(d instanceof u)||a>5||this.signal?.aborted)throw d;await U(d.seconds*1e3*(1+Math.random()*.2),this.signal)}},r=this.head,i=await e(()=>Ke(this.f,this.a.base,this.l,"never",this.signal));for(let s of $(t))await e(async()=>F(await this.go(...this.ask(i.id,await A(this.l,"share",s)))));await e(async()=>F(await this.go(...this.ask(r,await L(this.l,"share",{next:i.id})))));let o=await this.read();return this.head!==i.id&&await Ge(this.f,this.a.base,i.id,i.deleteToken).catch(()=>{}),o}};function Ye(n,t,e,r=Math.random()){let i=t?3e5:n<6e5?25e3+r*1e4:n<18e5?12e4:3e5;return Math.min(3e5,i*2**e)}var G=class{constructor(t,e){this.b=t;this.o=e}id="share";problem=null;offline=!1;newer=0;deliver=()=>{};active=Date.now();errors=0;ok=!1;timer;busy=null;again=!1;limit=0;rolling=!1;ready=null;stopped=!1;off=[];async start(t){this.deliver=t;let e=(i,o,s)=>{i&&(i.addEventListener(o,s),this.off.push(()=>i.removeEventListener(o,s)))},r=globalThis;r.addEventListener&&(e(globalThis,"focus",()=>void this.poll()),e(globalThis,"online",()=>void this.poll()),e(globalThis,"pagehide",()=>this.flush()),e(r.document,"visibilitychange",()=>r.document?.visibilityState==="visible"&&void this.poll())),await this.poll()}stop(){this.stopped=!0,clearTimeout(this.timer);for(let t of this.off.splice(0))t()}async remoteIds(){return this.ok?this.b.ids:null}poll(){if(this.busy)return this.again=!0,this.busy;let t=async()=>{do this.again=!1,await this.read();while(this.again&&!this.stopped)};return this.busy=t().finally(()=>this.busy=null)}bump(){this.active=Date.now()}async read(){clearTimeout(this.timer);try{let t=await this.b.read();this.offline=!1,this.errors=0,this.ok=!0,this.newer+=t.reduce((r,i)=>r+i.newer,0);let e=t.flatMap(r=>r.ops);if(e.length&&(this.active=Date.now(),this.deliver(e)),this.b.moved){this.b.moved=!1;let r=this.o.allowed().filter(i=>!this.b.ids.has(i.body.id));r.length&&await this.b.post(r).catch(()=>{})}this.b.big&&!this.rolling&&this.roll()}catch(t){t instanceof b?this.problem=t.kind:(this.offline=!0,this.errors++)}if(this.o.changed(),!this.stopped&&this.problem!=="gone"){let t=globalThis.document?.visibilityState==="hidden";this.timer=setTimeout(()=>void this.poll(),Ye(Date.now()-this.active,t,this.errors))}}lock(t,e=0){let r=this.o.lock,i=globalThis.navigator?.locks;return r?i?new Promise((o,s)=>{i.request(r,{signal:this.o.signal},async()=>{try{o(await t())}catch(a){s(a)}await U(e,this.o.signal)}).catch(s)}):U(Math.random()*5e3,this.o.signal).then(t):t()}get gap(){return Math.max(this.o.gap,this.limit)}async guarded(t){try{await this.lock(t,this.gap),this.offline=!1}catch(e){throw e instanceof u?(e.limit&&(this.limit=Math.max(this.limit,e.seconds*1e3)),e):e instanceof b?(this.problem=e.kind,this.o.changed(),new u(3600)):(this.offline=!0,this.o.changed(),e)}}async send(t){if(this.problem)throw new u(3600);this.bump(),await this.guarded(async()=>{await this.poll();let e=t.filter(r=>!this.b.ids.has(r.body.id));if(e.length){await this.b.post(e);for(let r of e)this.b.ids.add(r.body.id)}})}async prepare(t){try{this.ready=t.length&&JSON.stringify(t).length<4e4?await this.b.req(t):null}catch{this.ready=null}}flush(){let t=this.ready;this.ready=null,!(!t||this.problem||typeof t[1].body!="string"||t[1].body.length>64e3)&&(this.o.fetch??fetch)(t[0],{...t[1],keepalive:!0}).catch(()=>{})}async roll(){this.rolling=!0;try{await U(Math.random()*3e4,this.o.signal),await this.guarded(async()=>{if(await this.poll(),!this.b.big||!this.b.roll)return;let e=(await this.b.roll(this.o.allowed())).flatMap(r=>r.ops);e.length&&this.deliver(e)})}catch{}finally{this.rolling=!1}}};var Ze="Comments here are shared with everyone who has this page.",Xe=7*864e5,ve=["M12 16V4M7 9l5-5 5 5M5 20h14"],We=["M4 7a3 3 0 0 1 3-3h10a3 3 0 0 1 3 3v10a3 3 0 0 1-3 3H7a3 3 0 0 1-3-3z","M4 9.5h16M7.5 6.8h.01"],Ve="Only in this browser",Qe={held:"Written before this page was shared. Share it or keep it from the menu.",kept:"Written while Send my comments was off. It stays here.",chosen:"You chose to keep it here.",thread:"Part of a comment that stays in this browser.",unknown:"It stays in this browser and isn't sent to the shared copy."};function ke(n={}){return{id:"share",api:1,version:"0.4.1",needs:["sync","menu","notify","note","commentmark"],network:{when:"page-configured",to:["page"],says:"Sends the comments you choose to share, sealed so only people with this page can read them, to the sharing service the page names. That service sees when and how much is sent, and your network address."},async setup(t){let e=t.document,r=me(n.share??S("data-pipeup-share"),!0);if(r.kind==="off")return t.off(r.reason);if(!Q(e.id))return t.off("needs a document identity");let i=ee(e.id,r.key),o=await ie("share",{memory:t.ephemeral}),s=await o.get(`doc:${e.id}`),a=new q(e.me,s,be);a.hold(e.ops());let d=Promise.resolve(),l=()=>{d=d.then(()=>o.set(`doc:${e.id}`,a.saved())).catch(()=>{})};l();let f={gone:"The shared copy is gone",closed:"This page can't send to the shared copy; ask the author for the current file",full:"The shared copy is full; the author can start it again"},oe=new Set,se=(c,p)=>oe.has(c)||(oe.add(c),t.notify(p)),J=new Set,ae=()=>{let c=new Set;for(let p of e.ops()){if(p.body.kind!=="create"&&p.body.kind!=="reply")continue;let g=h.problem==="gone"?null:a.local(p);g&&(c.add(p.body.id),t.setCommentMark(p.body.id,{text:Ve,tip:Qe[g]}))}for(let p of J)c.has(p)||t.setCommentMark(p,null);J.clear();for(let p of c)J.add(p)},x=()=>{ae();for(let c of I)c.update();t.setStatus({text:ce()}),t.setComposerNote(a.send&&!a.noted&&h.problem!=="gone"?Ze:null),h.newer&&se("newer",`${h.newer} comments come from a newer version of Pipeup; this page can't show them yet.`),h.problem&&se(h.problem,f[h.problem]+(h.problem==="gone"?". Your comments stay in this browser.":"."))},de=(c,p)=>fetch(c,p),le=r.kind==="mailbox"?new j(r,i,de,t.signal):new K(r,i,de,t.signal,a.gen,c=>{a.gen=c,l()}),h=new G(le,{signal:t.signal,gap:1e4,lock:`pipeup-share:${e.id}`,allowed:()=>e.ops().filter(c=>a.sendable(c)),changed:x}),v=new M({id:"share",document:e,merge:async c=>{let p=await t.merge(c),g=new Set(e.ops().map(y=>y.body.id));for(let y of _(c))g.has(y)&&a.recv.add(y);return l(),p},transport:h,sendable:c=>{let p=a.sendable(c);return a.noted!==s?.noted&&l(),p},signal:t.signal,delay:2e3,gap:()=>h.gap}),Y;v.onState(()=>{x(),clearTimeout(Y),Y=setTimeout(()=>void h.prepare(v.pending()),1e3)});let Se=new URL(r.kind==="mailbox"?r.mailbox:r.base).host,ce=()=>{let c=v.waiting;return h.problem?f[h.problem]:a.send?h.offline||v.state==="offline"?"Shared \xB7 offline, sends when back":c?`Shared \xB7 ${c} change${c===1?"":"s"} waiting`:"Shared \xB7 up to date":"Shared \xB7 not sending your comments"},Ae=()=>{let c=le.expires;return h.problem==="gone"?"Your comments stay in this browser. The author can start sharing again.":[`Your comments are encrypted and sent to ${Se} so others with this page see them. The service can't read them. People who already have your comments, by file or live, could pass them on.`,t.ephemeral&&"This browser can't keep comments; the shared copy keeps the ones you send.",!o.lasting&&"This browser won't remember this choice.",c&&c-Date.now()<Xe&&`The shared copy expires on ${new Date(c).toLocaleDateString("en-GB",{day:"numeric",month:"long"})}.`].filter(Boolean).join(" ")},I=[],Z=(c,p,g,y,xe,Pe)=>I[I.push(t.addMenuItem({id:c,icon:p,label:g,hint:y,select:xe,checked:Pe}))-1],X=e.ops().filter(c=>a.held.has(c.body.id)&&(c.body.kind==="create"||c.body.kind==="reply")).length;if(Z("send",ve,()=>a.send||h.problem?ce():"Send my comments",Ae,()=>{a.send=!a.send,l(),v.rescan(),x()},()=>a.send),X){let c=o.lasting?"":" This browser won't remember this choice.",p=g=>()=>{a.decide(g),l();for(let y of I.splice(1))y.remove();v.rescan(),x()};Z("share-earlier",ve,()=>`Share my ${X} earlier comment${X===1?"":"s"}`,()=>`Send the comments you wrote before this page was shared.${c}`,p(!0)),Z("keep-earlier",We,()=>"Keep them in this browser",()=>`Never send the comments you wrote before this page was shared.${c}`,p(!1))}return x(),v.start().then(x,c=>globalThis.reportError?.(c)),e.onChange((c,p,g)=>{if(g==="local"&&p.length){for(let y of p)a.sendable(y);h.bump(),ae(),l()}}),()=>{clearTimeout(Y),v.stop()}}}}export{ke as createAddon,ke as default};
@@ -1 +1 @@
1
- var p=n=>new TextEncoder().encode(n),F=n=>new TextDecoder().decode(n);function m(n){let t="";for(let e=0;e<n.length;e+=32768)t+=String.fromCharCode(...n.subarray(e,e+32768));return btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function y(n){let t=n.replace(/-/g,"+").replace(/_/g,"/"),e=atob(t+"=".repeat((4-t.length%4)%4));return Uint8Array.from(e,r=>r.charCodeAt(0))}function w(n){let t="";for(let e=0;e<n.length;e+=32768)t+=String.fromCharCode(...n.subarray(e,e+32768));return btoa(t)}function H(n){return Uint8Array.from(atob(n),t=>t.charCodeAt(0))}var v=n=>crypto.getRandomValues(new Uint8Array(n));async function _(n){return new Uint8Array(await crypto.subtle.digest("SHA-256",n))}var st=n=>p(`pipeup/v1/doc:${n}`);async function Y(n,t,e,r){let i=await crypto.subtle.importKey("raw",n,"HKDF",!1,["deriveBits"]);return crypto.subtle.deriveBits({name:"HKDF",hash:"SHA-256",salt:st(t),info:p(e)},i,r)}function K(n,t){return{docId:n,key:async e=>crypto.subtle.importKey("raw",await Y(t,n,`pipeup/v1/${e}/key`,256),"AES-GCM",!1,["encrypt","decrypt"]),addr:async e=>m(new Uint8Array(await Y(t,n,`pipeup/v1/${e}/address`,128))),aad:e=>`pipeup/v1/${e}:${n}`}}var at=1e6,dt=1e3;async function V(n,t,e=1/0){let r=new Blob([n]).stream().pipeThrough(t).getReader(),i=[],o=0;for(;;){let{done:a,value:c}=await r.read();if(a)break;if(o+=c.length,o>e)throw r.cancel(),new Error("too large");i.push(c)}let s=new Uint8Array(o),d=0;for(let a of i)s.set(a,d),d+=a.length;return s}var g=(n,t,e)=>E(n,t,{pipeup:1,doc:n.docId,sealed:!1,ops:e});async function E(n,t,e){let r=p(JSON.stringify(e)),i=v(12),o=await crypto.subtle.encrypt({name:"AES-GCM",iv:i,additionalData:p(n.aad(t))},await n.key(t),await V(r,new CompressionStream("deflate-raw"))),s=new Uint8Array(13+o.byteLength);return s[0]=1,s.set(i,1),s.set(new Uint8Array(o),13),s}async function R(n,t,e){try{if(e.length<29||e[0]!==1)return null;let r=await crypto.subtle.decrypt({name:"AES-GCM",iv:e.slice(1,13),additionalData:p(n.aad(t))},await n.key(t),e.slice(13));return JSON.parse(F(await V(new Uint8Array(r),new DecompressionStream("deflate-raw"),at)))}catch{return null}}function D(n,t){let e=t;if(e?.pipeup!==1||e.doc!==n.docId||!Array.isArray(e.ops)||e.ops.length>dt)return null;let r=0;for(let i of e.ops){let o=i?.body?.v;typeof o=="number"&&o!==1&&r++}return{ops:e.ops,newer:r}}async function G(n,t,e){return D(n,await R(n,t,e))}var J=n=>`pu1.${m(n)}`,Z=n=>{if(!/^pu1\.[A-Za-z0-9_-]+$/.test(n))return null;try{return y(n.slice(4))}catch{return null}};var l=class extends Error{constructor(e,r=!1){super(`try again in ${e} s`);this.seconds=e;this.limit=r;this.name="RetryAfter"}};var ct=100,W=5e3,lt=5e3,pt=3e5,ut=3600,O=class{constructor(t){this.o=t}state="idle";lastOk=0;known=new Set;outbox=new Map;rejected=new Set;inbound=[];inboundTimer=0;sendTimer=0;lastSend=0;backoff=0;off=null;listeners=new Set;stopped=!1;get waiting(){return this.outbox.size}pending(){return[...this.outbox.values()]}onState(t){return this.listeners.add(t),()=>this.listeners.delete(t)}emit(t){t&&(this.state=t);for(let e of[...this.listeners])e()}async start(){let{document:t,transport:e,signal:r}=this.o;this.off=t.onChange((o,s,d)=>{if(d===this.o.id)return;let a=!1;for(let c of s)this.want(c)&&(a=this.outbox.set(c.body.id,c).size>0||a);a&&this.schedule(),this.emit()}),r.addEventListener("abort",()=>this.stop(),{once:!0}),await e.start(o=>this.deliver(o));let i=await e.remoteIds?.();if(i)for(let o of i)this.known.add(o);this.rescan()}stop(){this.stopped||(this.stopped=!0,this.off?.(),clearTimeout(this.inboundTimer),clearTimeout(this.sendTimer),this.o.transport.stop())}want(t){return!this.known.has(t.body.id)&&!this.rejected.has(t.body.id)&&this.o.sendable(t)}rescan(){this.outbox.clear();for(let t of this.o.document.ops())this.want(t)&&this.outbox.set(t.body.id,t);this.schedule(),this.emit()}deliver(t){this.inbound.push(...t),this.inboundTimer||(this.inboundTimer=setTimeout(()=>void this.drain(),ct))}async drain(){this.inboundTimer=0;let t=this.inbound.splice(0),e=t.map(i=>i?.body?.id).filter(i=>typeof i=="string");for(let i=0;i<t.length;i+=W)try{await this.o.merge(t.slice(i,i+W))}catch(o){o?.name!=="UnsavedChangeError"&&globalThis.reportError?.(o)}let r=new Set(this.o.document.ops().map(i=>i.body.id));for(let i of e)r.has(i)?(this.known.add(i),this.outbox.delete(i)):this.rejected.add(i);this.lastOk=Date.now(),this.emit()}schedule(t=this.o.delay??0){if(this.stopped||this.sendTimer||this.outbox.size===0)return;let e=typeof this.o.gap=="function"?this.o.gap():this.o.gap??0,r=Math.max(t,this.lastSend+e-Date.now(),this.backoff);this.sendTimer=setTimeout(()=>void this.send(),r)}async send(){if(this.sendTimer=0,this.stopped||this.o.signal.aborted||this.outbox.size===0)return;let t=[...this.outbox.values()].slice(0,this.o.batch??500);this.emit("sending");try{await this.o.transport.send(t);for(let e of t)this.known.add(e.body.id),this.outbox.delete(e.body.id);this.lastSend=Date.now(),this.lastOk=this.lastSend,this.backoff=0,this.emit("idle")}catch(e){e instanceof l?(this.backoff=Math.min(e.seconds,ut)*1e3*(1+Math.random()*.2),this.emit("limited")):(this.backoff=Math.min(pt,this.backoff?this.backoff*2:lt),this.emit("offline"))}this.schedule()}};var qt=2n**256n-2n**32n-977n;var ht="sharing isn't set up for this page",B="data-pipeup-share isn't a sharing address",mt=/^(localhost|127\.0\.0\.1|\[::1\])$/,Q=/^[A-Za-z0-9_-]{43}$/,x=n=>({kind:"off",reason:n});function tt(n,t=!1){let e=n?.trim();if(!e)return x(ht);let r;try{r=new URL(e)}catch{return x(B)}if(r.protocol!=="https:"&&!(t&&r.protocol==="http:"&&mt.test(r.hostname)))return x(B);let i=r.origin+r.pathname,o=r.hash.slice(1);if(o.startsWith("pm1.")){let[d,a,...c]=o.slice(4).split(".");return!Q.test(d??"")||c.length||a!==void 0&&!/^[A-Za-z0-9_-]+$/.test(a)||r.search||!/\/m\/[A-Za-z0-9_-]{22,64}$/.test(i)?x(B):{kind:"mailbox",mailbox:i,key:y(d),...a?{token:a}:{}}}let s=/^\?([A-Za-z0-9_-]{8,64})$/.exec(r.search)?.[1];return!s||!Q.test(o)?x(B):{kind:"privatebin",base:i,paste:s,key:y(o)}}var f=class extends Error{constructor(e){super(e);this.kind=e;this.name="Problem"}},et={Accept:"application/json"},M=(n,t,e)=>n(t,{headers:et,credentials:"omit",signal:e}),A=n=>({method:"POST",headers:et,credentials:"omit",body:JSON.stringify(n)}),nt=n=>{let t={403:"closed",404:"gone",507:"full"}[n];return t&&new f(t)};async function k(n){let t=await n.text(),e=t.length<1e7&&JSON.parse(t);if(!e||typeof e!="object")throw new Error("the answer was not usable");return[e,t.length]}function U(n,t=9e5){let e=[],r=0;for(let i of n)r+=JSON.stringify(i).length,(!e.length||r>t||e.at(-1).length>=500)&&(e.push([]),r=JSON.stringify(i).length),e.at(-1).push(i);return e}var S=(n,t)=>new Promise(e=>{let r=setTimeout(e,n);t?.addEventListener("abort",()=>{clearTimeout(r),e()},{once:!0})}),L=(n,t=10)=>{let e=Number(n.headers.get("Retry-After"));return e>0?Math.min(e,3600):t},P=n=>n.map(t=>t?.body?.id).filter(t=>typeof t=="string");var yt=524288,gt=1e3,bt=async n=>m(await _(p(n))).slice(0,22),$=class{constructor(t,e,r,i){this.a=t;this.l=e;this.f=r;this.signal=i}ids=new Set;expires=null;moved=!1;big=!1;cursor="";seen=new Set;memo=null;async read(){let t=[],e=0;for(let r=0;r<gt;){let i=`${this.a.mailbox}/ops${this.cursor?`?since=${encodeURIComponent(this.cursor)}`:""}`,o=await M(this.f,i,this.signal);if(o.status===404)throw new f("gone");if(o.status===409&&e++<2){this.cursor="";continue}if(!o.ok)throw new Error(`HTTP ${o.status}`);r++;let[s]=await k(o);for(let d of Array.isArray(s.batches)?s.batches:[]){if(typeof d?.id!="string"||typeof d.ct!="string"||this.seen.has(d.id))continue;this.seen.add(d.id);let a=Z(d.ct),c=a&&await G(this.l,"share",a);if(c){t.push(c);for(let u of P(c.ops))this.ids.add(u)}}if(typeof s.next=="string"&&(this.cursor=s.next),this.expires=typeof s.expires=="string"&&Date.parse(s.expires)||null,s.more!==!0)break}return t}async req(t){let e=t.map(o=>o.body.id).join();if(this.memo?.key!==e){let o=J(await g(this.l,"share",t));this.memo={key:e,ct:o,id:await bt(o)}}let{ct:r,id:i}=this.memo;return[`${this.a.mailbox}/ops`,A({id:i,ct:r,token:this.a.token})]}async post(t){for(let e of U(t))await this.one(e)}async one(t){let[e,r]=await this.req(t),i=async()=>{let a=t.length>>1;await this.one(t.slice(0,a)),await this.one(t.slice(a))};if(r.body.length>yt&&t.length>1)return i();let o=await this.f(e,{...r,signal:this.signal}),s=o.status;if(s===200||s===201||s===400)return;if(s===413&&t.length>1)return i();let d=nt(s);if(d)throw d;if(s===429){let[a]=await k(o).catch(()=>[{}]),c=Number(a.retryAfter);throw new l(o.headers.get("Retry-After")?L(o):c>0?Math.min(c,3600):10)}throw new Error(`HTTP ${s}`)}};var wt=256e3,vt=16,xt=/^[A-Za-z0-9_-]{8,64}$/,rt=()=>[w(v(16)),w(v(8)),1e5,256,128,"aes","gcm","none"],At=(n,t)=>({v:2,adata:rt(),ct:w(t),pasteid:n,parentid:n});async function I(n){if(n.status===429)throw new l(L(n));if(!n.ok)throw new Error(`HTTP ${n.status}`);let[t]=await k(n);if(t.status===0)return t;let e=Number(/\d+/.exec(String(t.message??""))?.[0]);throw new l(e>=1&&e<=3600?e:30,!0)}async function kt(n,t,e,r="never",i){let o=w(await g(e,"share",[])),s=await I(await n(t,{...A({v:2,adata:[rt(),"plaintext",1,0],ct:o,meta:{expire:r}}),signal:i}));if(typeof s.id!="string"||typeof s.deletetoken!="string")throw new Error("the answer had no paste id");return{id:s.id,deleteToken:s.deletetoken}}async function St(n,t,e,r){return n(t,A({pasteid:e,deletetoken:r}))}async function Pt(n,t,e,r){let i=await M(n,`${t}?${e}`,r);if(i.status===404)return null;if(!i.ok)throw new Error(`HTTP ${i.status}`);let[o,s]=await k(i);if(o.status!==0)return null;let d=o.meta?.time_to_live;return{j:o,size:s,ttl:typeof d=="number"&&d>0?d*1e3:null}}var C=class{constructor(t,e,r,i,o,s=()=>{}){this.a=t;this.l=e;this.f=r;this.signal=i;this.onGen=s;this.head=o||t.paste,this.trail.push(t.paste)}ids=new Set;expires=null;moved=!1;big=!1;head;trail=[];seen=new Map;async scan(t,e){let r;for(let i of Array.isArray(t)?t:[]){if(typeof i?.id!="string"||typeof i.ct!="string")continue;let o=this.seen.get(i.id);if(o===void 0){o=null;let s=null;try{i.ct.length<14e5&&(s=H(i.ct))}catch{}let d=s&&await R(this.l,"share",s),a=d?.next,c=typeof a=="string"?null:D(this.l,d);if(typeof a=="string"&&xt.test(a))o=a;else if(c){e.push(c);for(let u of P(c.ops))this.ids.add(u)}this.seen.set(i.id,o)}r??=o??void 0}return r}async read(){let t=[],e=this.head,r=!1,i=!1;for(let o=0;;){let s=await Pt(this.f,this.a.base,e,this.signal);if(!s){if(i)break;if(!r&&e!==this.a.paste){r=!0,e=this.a.paste;continue}throw new f("gone")}i=!0,e!==this.head&&(this.head=e,this.trail.push(e),this.ids.clear(),this.moved=!0,this.onGen(e));let d=s.j.comments,a=await this.scan(d,t);this.expires=s.ttl&&Date.now()+s.ttl;let c=(Array.isArray(d)?d[0]?.ct?.length:0)??0;if(this.big=!a&&s.size>wt&&s.size>2*c,!a||++o>=vt)break;e=a}return t}ask(t,e){return[this.a.base,A(At(t,e))]}async req(t){return this.ask(this.head,await g(this.l,"share",t))}go(t,e){return this.f(t,{...e,signal:this.signal})}async post(t){for(let e of U(t))await I(await this.go(...await this.req(e)))}async roll(t){let e=async s=>{for(let d=0;;d++)try{return await s()}catch(a){if(!(a instanceof l)||d>5||this.signal?.aborted)throw a;await S(a.seconds*1e3*(1+Math.random()*.2),this.signal)}},r=this.head,i=await e(()=>kt(this.f,this.a.base,this.l,"never",this.signal));for(let s of U(t))await e(async()=>I(await this.go(...this.ask(i.id,await g(this.l,"share",s)))));await e(async()=>I(await this.go(...this.ask(r,await E(this.l,"share",{next:i.id})))));let o=await this.read();return this.head!==i.id&&await St(this.f,this.a.base,i.id,i.deleteToken).catch(()=>{}),o}};function Tt(n,t,e,r=Math.random()){let i=t?3e5:n<6e5?25e3+r*1e4:n<18e5?12e4:3e5;return Math.min(3e5,i*2**e)}var z=class{constructor(t,e){this.b=t;this.o=e}id="share";problem=null;offline=!1;newer=0;deliver=()=>{};active=Date.now();errors=0;ok=!1;timer;busy=null;again=!1;limit=0;rolling=!1;ready=null;stopped=!1;off=[];async start(t){this.deliver=t;let e=(i,o,s)=>{i&&(i.addEventListener(o,s),this.off.push(()=>i.removeEventListener(o,s)))},r=globalThis;r.addEventListener&&(e(globalThis,"focus",()=>void this.poll()),e(globalThis,"online",()=>void this.poll()),e(globalThis,"pagehide",()=>this.flush()),e(r.document,"visibilitychange",()=>r.document?.visibilityState==="visible"&&void this.poll())),await this.poll()}stop(){this.stopped=!0,clearTimeout(this.timer);for(let t of this.off.splice(0))t()}async remoteIds(){return this.ok?this.b.ids:null}poll(){if(this.busy)return this.again=!0,this.busy;let t=async()=>{do this.again=!1,await this.read();while(this.again&&!this.stopped)};return this.busy=t().finally(()=>this.busy=null)}bump(){this.active=Date.now()}async read(){clearTimeout(this.timer);try{let t=await this.b.read();this.offline=!1,this.errors=0,this.ok=!0,this.newer+=t.reduce((r,i)=>r+i.newer,0);let e=t.flatMap(r=>r.ops);if(e.length&&(this.active=Date.now(),this.deliver(e)),this.b.moved){this.b.moved=!1;let r=this.o.allowed().filter(i=>!this.b.ids.has(i.body.id));r.length&&await this.b.post(r).catch(()=>{})}this.b.big&&!this.rolling&&this.roll()}catch(t){t instanceof f?this.problem=t.kind:(this.offline=!0,this.errors++)}if(this.o.changed(),!this.stopped&&this.problem!=="gone"){let t=globalThis.document?.visibilityState==="hidden";this.timer=setTimeout(()=>void this.poll(),Tt(Date.now()-this.active,t,this.errors))}}lock(t,e=0){let r=this.o.lock,i=globalThis.navigator?.locks;return r?i?new Promise((o,s)=>{i.request(r,{signal:this.o.signal},async()=>{try{o(await t())}catch(d){s(d)}await S(e,this.o.signal)}).catch(s)}):S(Math.random()*5e3,this.o.signal).then(t):t()}get gap(){return Math.max(this.o.gap,this.limit)}async guarded(t){try{await this.lock(t,this.gap),this.offline=!1}catch(e){throw e instanceof l?(e.limit&&(this.limit=Math.max(this.limit,e.seconds*1e3)),e):e instanceof f?(this.problem=e.kind,this.o.changed(),new l(3600)):(this.offline=!0,this.o.changed(),e)}}async send(t){if(this.problem)throw new l(3600);this.bump(),await this.guarded(async()=>{await this.poll();let e=t.filter(r=>!this.b.ids.has(r.body.id));if(e.length){await this.b.post(e);for(let r of e)this.b.ids.add(r.body.id)}})}async prepare(t){try{this.ready=t.length&&JSON.stringify(t).length<4e4?await this.b.req(t):null}catch{this.ready=null}}flush(){let t=this.ready;this.ready=null,!(!t||this.problem||typeof t[1].body!="string"||t[1].body.length>64e3)&&(this.o.fetch??fetch)(t[0],{...t[1],keepalive:!0}).catch(()=>{})}async roll(){this.rolling=!0;try{await S(Math.random()*3e4,this.o.signal),await this.guarded(async()=>{if(await this.poll(),!this.b.big||!this.b.roll)return;let e=(await this.b.roll(this.o.allowed())).flatMap(r=>r.ops);e.length&&this.deliver(e)})}catch{}finally{this.rolling=!1}}};async function Ue(n,t){let e=tt(t.share,t.local);if(e.kind==="off")throw new Error(e.reason);let r=K(n.id,e.key),i=t.fetch??((h,T)=>fetch(h,T)),o=e.kind==="mailbox"?new $(e,r,i,t.signal):new C(e,r,i,t.signal),s=new Set,d=t.sendable??(h=>s.has(h.body.id)||h.body.author===n.me),a=t.signal??new AbortController().signal,c=new z(o,{signal:a,gap:t.gap??1e4,lock:!1,allowed:()=>n.ops().filter(d),changed(){}}),u=new O({id:"share",document:n,merge:async h=>{let T=await n.merge(h,"share"),N=new Set(n.ops().map(b=>b.body.id));for(let b of P(h))N.has(b)&&s.add(b);return T},transport:c,sendable:d,signal:a,delay:t.delay??0,gap:()=>c.gap});return await u.start(),{problem:()=>c.problem,waiting:()=>u.waiting,stop:()=>u.stop(),flush:async(h=12e4)=>(await c.poll(),new Promise((T,N)=>{let b=Date.now(),it=setInterval(j,250),ot=u.onState(j);function q(X){clearInterval(it),ot(),X?N(X):T()}function j(){if(c.problem)return q(new Error(`sharing stopped: the shared copy is ${c.problem==="gone"?"gone":c.problem==="full"?"full":"refusing this page"}`));if(!u.waiting&&u.state!=="sending")return q();Date.now()-b>h&&q(new Error("timed out before everything was sent"))}u.rescan(),j()}))}}export{Ue as connectShare};
1
+ var p=n=>new TextEncoder().encode(n),F=n=>new TextDecoder().decode(n);function g(n){let t="";for(let e=0;e<n.length;e+=32768)t+=String.fromCharCode(...n.subarray(e,e+32768));return btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function m(n){let t=n.replace(/-/g,"+").replace(/_/g,"/"),e=atob(t+"=".repeat((4-t.length%4)%4));return Uint8Array.from(e,r=>r.charCodeAt(0))}function w(n){let t="";for(let e=0;e<n.length;e+=32768)t+=String.fromCharCode(...n.subarray(e,e+32768));return btoa(t)}function H(n){return Uint8Array.from(atob(n),t=>t.charCodeAt(0))}var v=n=>crypto.getRandomValues(new Uint8Array(n));async function E(n){return new Uint8Array(await crypto.subtle.digest("SHA-256",n))}var at=n=>p(`pipeup/v1/doc:${n}`);async function Y(n,t,e,r){let i=await crypto.subtle.importKey("raw",n,"HKDF",!1,["deriveBits"]);return crypto.subtle.deriveBits({name:"HKDF",hash:"SHA-256",salt:at(t),info:p(e)},i,r)}function K(n,t){return{docId:n,key:async e=>crypto.subtle.importKey("raw",await Y(t,n,`pipeup/v1/${e}/key`,256),"AES-GCM",!1,["encrypt","decrypt"]),addr:async e=>g(new Uint8Array(await Y(t,n,`pipeup/v1/${e}/address`,128))),aad:e=>`pipeup/v1/${e}:${n}`}}var dt=1e6,lt=1e3;async function V(n,t,e=1/0){let r=new Blob([n]).stream().pipeThrough(t).getReader(),i=[],o=0;for(;;){let{done:a,value:l}=await r.read();if(a)break;if(o+=l.length,o>e)throw r.cancel(),new Error("too large");i.push(l)}let s=new Uint8Array(o),d=0;for(let a of i)s.set(a,d),d+=a.length;return s}var y=(n,t,e)=>_(n,t,{pipeup:1,doc:n.docId,sealed:!1,ops:e});async function _(n,t,e){let r=p(JSON.stringify(e)),i=v(12),o=await crypto.subtle.encrypt({name:"AES-GCM",iv:i,additionalData:p(n.aad(t))},await n.key(t),await V(r,new CompressionStream("deflate-raw"))),s=new Uint8Array(13+o.byteLength);return s[0]=1,s.set(i,1),s.set(new Uint8Array(o),13),s}async function R(n,t,e){try{if(e.length<29||e[0]!==1)return null;let r=await crypto.subtle.decrypt({name:"AES-GCM",iv:e.slice(1,13),additionalData:p(n.aad(t))},await n.key(t),e.slice(13));return JSON.parse(F(await V(new Uint8Array(r),new DecompressionStream("deflate-raw"),dt)))}catch{return null}}function D(n,t){let e=t;if(e?.pipeup!==1||e.doc!==n.docId||!Array.isArray(e.ops)||e.ops.length>lt)return null;let r=0;for(let i of e.ops){let o=i?.body?.v;typeof o=="number"&&o!==1&&r++}return{ops:e.ops,newer:r}}async function G(n,t,e){return D(n,await R(n,t,e))}var J=n=>`pu1.${g(n)}`,Z=n=>{if(!/^pu1\.[A-Za-z0-9_-]+$/.test(n))return null;try{return m(n.slice(4))}catch{return null}};var c=class extends Error{constructor(e,r=!1){super(`try again in ${e} s`);this.seconds=e;this.limit=r;this.name="RetryAfter"}};var ct=100,W=5e3,pt=5e3,ut=3e5,ft=3600,O=class{constructor(t){this.o=t}state="idle";lastOk=0;known=new Set;outbox=new Map;rejected=new Set;inbound=[];inboundTimer=0;sendTimer=0;lastSend=0;backoff=0;off=null;listeners=new Set;stopped=!1;get waiting(){return this.outbox.size}pending(){return[...this.outbox.values()]}onState(t){return this.listeners.add(t),()=>this.listeners.delete(t)}emit(t){t&&(this.state=t);for(let e of[...this.listeners])e()}async start(){let{document:t,transport:e,signal:r}=this.o;this.off=t.onChange((o,s,d)=>{if(d===this.o.id)return;let a=!1;for(let l of s)this.want(l)&&(a=this.outbox.set(l.body.id,l).size>0||a);a&&this.schedule(),this.emit()}),r.addEventListener("abort",()=>this.stop(),{once:!0}),await e.start(o=>this.deliver(o));let i=await e.remoteIds?.();if(i)for(let o of i)this.known.add(o);this.rescan()}stop(){this.stopped||(this.stopped=!0,this.off?.(),clearTimeout(this.inboundTimer),clearTimeout(this.sendTimer),this.o.transport.stop())}want(t){return!this.known.has(t.body.id)&&!this.rejected.has(t.body.id)&&this.o.sendable(t)}rescan(){this.outbox.clear();for(let t of this.o.document.ops())this.want(t)&&this.outbox.set(t.body.id,t);this.schedule(),this.emit()}deliver(t){this.inbound.push(...t),this.inboundTimer||(this.inboundTimer=setTimeout(()=>void this.drain(),ct))}async drain(){this.inboundTimer=0;let t=this.inbound.splice(0),e=t.map(i=>i?.body?.id).filter(i=>typeof i=="string");for(let i=0;i<t.length;i+=W)try{await this.o.merge(t.slice(i,i+W))}catch(o){o?.name!=="UnsavedChangeError"&&globalThis.reportError?.(o)}let r=new Set(this.o.document.ops().map(i=>i.body.id));for(let i of e)r.has(i)?(this.known.add(i),this.outbox.delete(i)):this.rejected.add(i);this.lastOk=Date.now(),this.emit()}schedule(t=this.o.delay??0){if(this.stopped||this.sendTimer||this.outbox.size===0)return;let e=typeof this.o.gap=="function"?this.o.gap():this.o.gap??0,r=Math.max(t,this.lastSend+e-Date.now(),this.backoff);this.sendTimer=setTimeout(()=>void this.send(),r)}async send(){if(this.sendTimer=0,this.stopped||this.o.signal.aborted||this.outbox.size===0)return;let t=[...this.outbox.values()].slice(0,this.o.batch??500);this.emit("sending");try{await this.o.transport.send(t);for(let e of t)this.known.add(e.body.id),this.outbox.delete(e.body.id);this.lastSend=Date.now(),this.lastOk=this.lastSend,this.backoff=0,this.emit("idle")}catch(e){e instanceof c?(this.backoff=Math.min(e.seconds,ft)*1e3*(1+Math.random()*.2),this.emit("limited")):(this.backoff=Math.min(ut,this.backoff?this.backoff*2:pt),this.emit("offline"))}this.schedule()}};var Ht=2n**256n-2n**32n-977n;var gt="sharing isn't set up for this page",B="data-pipeup-share isn't a sharing address",mt=/^(localhost|127\.0\.0\.1|\[::1\])$/,Q=/^[A-Za-z0-9_-]{43}$/,x=n=>({kind:"off",reason:n});function tt(n,t=!1){let e=n?.trim();if(!e)return x(gt);let r;try{r=new URL(e)}catch{return x(B)}if(r.protocol!=="https:"&&!(t&&r.protocol==="http:"&&mt.test(r.hostname)))return x(B);let i=r.origin+r.pathname,o=r.hash.slice(1);if(o.startsWith("pm1.")){let[d,a,...l]=o.slice(4).split(".");return!Q.test(d??"")||l.length||a!==void 0&&!/^[A-Za-z0-9_-]+$/.test(a)||r.search||!/\/m\/[A-Za-z0-9_-]{22,64}$/.test(i)?x(B):{kind:"mailbox",mailbox:i,key:m(d),...a?{token:a}:{}}}let s=/^\?([A-Za-z0-9_-]{8,64})$/.exec(r.search)?.[1];return!s||!Q.test(o)?x(B):{kind:"privatebin",base:i,paste:s,key:m(o)}}var f=class extends Error{constructor(e){super(e);this.kind=e;this.name="Problem"}},et={Accept:"application/json"},M=(n,t,e)=>n(t,{headers:et,credentials:"omit",signal:e}),A=n=>({method:"POST",headers:et,credentials:"omit",body:JSON.stringify(n)}),nt=n=>{let t={403:"closed",404:"gone",507:"full"}[n];return t&&new f(t)};async function k(n){let t=await n.text(),e=t.length<1e7&&JSON.parse(t);if(!e||typeof e!="object")throw new Error("the answer was not usable");return[e,t.length]}function U(n,t=9e5){let e=[],r=0;for(let i of n)r+=JSON.stringify(i).length,(!e.length||r>t||e.at(-1).length>=500)&&(e.push([]),r=JSON.stringify(i).length),e.at(-1).push(i);return e}var S=(n,t)=>new Promise(e=>{let r=setTimeout(e,n);t?.addEventListener("abort",()=>{clearTimeout(r),e()},{once:!0})}),L=(n,t=10)=>{let e=Number(n.headers.get("Retry-After"));return e>0?Math.min(e,3600):t},P=n=>n.map(t=>t?.body?.id).filter(t=>typeof t=="string");var yt=524288,bt=1e3,wt=async n=>g(await E(p(n))).slice(0,22),$=class{constructor(t,e,r,i){this.a=t;this.l=e;this.f=r;this.signal=i}ids=new Set;expires=null;moved=!1;big=!1;cursor="";seen=new Set;memo=null;async read(){let t=[],e=0;for(let r=0;r<bt;){let i=`${this.a.mailbox}/ops${this.cursor?`?since=${encodeURIComponent(this.cursor)}`:""}`,o=await M(this.f,i,this.signal);if(o.status===404)throw new f("gone");if(o.status===409&&e++<2){this.cursor="";continue}if(!o.ok)throw new Error(`HTTP ${o.status}`);r++;let[s]=await k(o);for(let d of Array.isArray(s.batches)?s.batches:[]){if(typeof d?.id!="string"||typeof d.ct!="string"||this.seen.has(d.id))continue;this.seen.add(d.id);let a=Z(d.ct),l=a&&await G(this.l,"share",a);if(l){t.push(l);for(let u of P(l.ops))this.ids.add(u)}}if(typeof s.next=="string"&&(this.cursor=s.next),this.expires=typeof s.expires=="string"&&Date.parse(s.expires)||null,s.more!==!0)break}return t}async req(t){let e=t.map(o=>o.body.id).join();if(this.memo?.key!==e){let o=J(await y(this.l,"share",t));this.memo={key:e,ct:o,id:await wt(o)}}let{ct:r,id:i}=this.memo;return[`${this.a.mailbox}/ops`,A({id:i,ct:r,token:this.a.token})]}async post(t){for(let e of U(t))await this.one(e)}async one(t){let[e,r]=await this.req(t),i=async()=>{let a=t.length>>1;await this.one(t.slice(0,a)),await this.one(t.slice(a))};if(r.body.length>yt&&t.length>1)return i();let o=await this.f(e,{...r,signal:this.signal}),s=o.status;if(s===200||s===201||s===400)return;if(s===413&&t.length>1)return i();let d=nt(s);if(d)throw d;if(s===429){let[a]=await k(o).catch(()=>[{}]),l=Number(a.retryAfter);throw new c(o.headers.get("Retry-After")?L(o):l>0?Math.min(l,3600):10)}throw new Error(`HTTP ${s}`)}};var vt=256e3,xt=16,At=/^[A-Za-z0-9_-]{8,64}$/,rt=()=>[w(v(16)),w(v(8)),1e5,256,128,"aes","gcm","none"],kt=(n,t)=>({v:2,adata:rt(),ct:w(t),pasteid:n,parentid:n});async function I(n){if(n.status===429)throw new c(L(n));if(!n.ok)throw new Error(`HTTP ${n.status}`);let[t]=await k(n);if(t.status===0)return t;let e=Number(/\d+/.exec(String(t.message??""))?.[0]);throw new c(e>=1&&e<=3600?e:30,!0)}async function St(n,t,e,r="never",i){let o=w(await y(e,"share",[])),s=await I(await n(t,{...A({v:2,adata:[rt(),"plaintext",1,0],ct:o,meta:{expire:r}}),signal:i}));if(typeof s.id!="string"||typeof s.deletetoken!="string")throw new Error("the answer had no paste id");return{id:s.id,deleteToken:s.deletetoken}}async function Pt(n,t,e,r){return n(t,A({pasteid:e,deletetoken:r}))}async function Tt(n,t,e,r){let i=await M(n,`${t}?${e}`,r);if(i.status===404)return null;if(!i.ok)throw new Error(`HTTP ${i.status}`);let[o,s]=await k(i);if(o.status!==0)return null;let d=o.meta?.time_to_live;return{j:o,size:s,ttl:typeof d=="number"&&d>0?d*1e3:null}}var C=class{constructor(t,e,r,i,o,s=()=>{}){this.a=t;this.l=e;this.f=r;this.signal=i;this.onGen=s;this.head=o||t.paste,this.trail.push(t.paste)}ids=new Set;expires=null;moved=!1;big=!1;head;trail=[];seen=new Map;async scan(t,e){let r;for(let i of Array.isArray(t)?t:[]){if(typeof i?.id!="string"||typeof i.ct!="string")continue;let o=this.seen.get(i.id);if(o===void 0){o=null;let s=null;try{i.ct.length<14e5&&(s=H(i.ct))}catch{}let d=s&&await R(this.l,"share",s),a=d?.next,l=typeof a=="string"?null:D(this.l,d);if(typeof a=="string"&&At.test(a))o=a;else if(l){e.push(l);for(let u of P(l.ops))this.ids.add(u)}this.seen.set(i.id,o)}r??=o??void 0}return r}async read(){let t=[],e=this.head,r=!1,i=!1;for(let o=0;;){let s=await Tt(this.f,this.a.base,e,this.signal);if(!s){if(i)break;if(!r&&e!==this.a.paste){r=!0,e=this.a.paste;continue}throw new f("gone")}i=!0,e!==this.head&&(this.head=e,this.trail.push(e),this.ids.clear(),this.moved=!0,this.onGen(e));let d=s.j.comments,a=await this.scan(d,t);this.expires=s.ttl&&Date.now()+s.ttl;let l=(Array.isArray(d)?d[0]?.ct?.length:0)??0;if(this.big=!a&&s.size>vt&&s.size>2*l,!a||++o>=xt)break;e=a}return t}ask(t,e){return[this.a.base,A(kt(t,e))]}async req(t){return this.ask(this.head,await y(this.l,"share",t))}go(t,e){return this.f(t,{...e,signal:this.signal})}async post(t){for(let e of U(t))await I(await this.go(...await this.req(e)))}async roll(t){let e=async s=>{for(let d=0;;d++)try{return await s()}catch(a){if(!(a instanceof c)||d>5||this.signal?.aborted)throw a;await S(a.seconds*1e3*(1+Math.random()*.2),this.signal)}},r=this.head,i=await e(()=>St(this.f,this.a.base,this.l,"never",this.signal));for(let s of U(t))await e(async()=>I(await this.go(...this.ask(i.id,await y(this.l,"share",s)))));await e(async()=>I(await this.go(...this.ask(r,await _(this.l,"share",{next:i.id})))));let o=await this.read();return this.head!==i.id&&await Pt(this.f,this.a.base,i.id,i.deleteToken).catch(()=>{}),o}};function Ot(n,t,e,r=Math.random()){let i=t?3e5:n<6e5?25e3+r*1e4:n<18e5?12e4:3e5;return Math.min(3e5,i*2**e)}var z=class{constructor(t,e){this.b=t;this.o=e}id="share";problem=null;offline=!1;newer=0;deliver=()=>{};active=Date.now();errors=0;ok=!1;timer;busy=null;again=!1;limit=0;rolling=!1;ready=null;stopped=!1;off=[];async start(t){this.deliver=t;let e=(i,o,s)=>{i&&(i.addEventListener(o,s),this.off.push(()=>i.removeEventListener(o,s)))},r=globalThis;r.addEventListener&&(e(globalThis,"focus",()=>void this.poll()),e(globalThis,"online",()=>void this.poll()),e(globalThis,"pagehide",()=>this.flush()),e(r.document,"visibilitychange",()=>r.document?.visibilityState==="visible"&&void this.poll())),await this.poll()}stop(){this.stopped=!0,clearTimeout(this.timer);for(let t of this.off.splice(0))t()}async remoteIds(){return this.ok?this.b.ids:null}poll(){if(this.busy)return this.again=!0,this.busy;let t=async()=>{do this.again=!1,await this.read();while(this.again&&!this.stopped)};return this.busy=t().finally(()=>this.busy=null)}bump(){this.active=Date.now()}async read(){clearTimeout(this.timer);try{let t=await this.b.read();this.offline=!1,this.errors=0,this.ok=!0,this.newer+=t.reduce((r,i)=>r+i.newer,0);let e=t.flatMap(r=>r.ops);if(e.length&&(this.active=Date.now(),this.deliver(e)),this.b.moved){this.b.moved=!1;let r=this.o.allowed().filter(i=>!this.b.ids.has(i.body.id));r.length&&await this.b.post(r).catch(()=>{})}this.b.big&&!this.rolling&&this.roll()}catch(t){t instanceof f?this.problem=t.kind:(this.offline=!0,this.errors++)}if(this.o.changed(),!this.stopped&&this.problem!=="gone"){let t=globalThis.document?.visibilityState==="hidden";this.timer=setTimeout(()=>void this.poll(),Ot(Date.now()-this.active,t,this.errors))}}lock(t,e=0){let r=this.o.lock,i=globalThis.navigator?.locks;return r?i?new Promise((o,s)=>{i.request(r,{signal:this.o.signal},async()=>{try{o(await t())}catch(d){s(d)}await S(e,this.o.signal)}).catch(s)}):S(Math.random()*5e3,this.o.signal).then(t):t()}get gap(){return Math.max(this.o.gap,this.limit)}async guarded(t){try{await this.lock(t,this.gap),this.offline=!1}catch(e){throw e instanceof c?(e.limit&&(this.limit=Math.max(this.limit,e.seconds*1e3)),e):e instanceof f?(this.problem=e.kind,this.o.changed(),new c(3600)):(this.offline=!0,this.o.changed(),e)}}async send(t){if(this.problem)throw new c(3600);this.bump(),await this.guarded(async()=>{await this.poll();let e=t.filter(r=>!this.b.ids.has(r.body.id));if(e.length){await this.b.post(e);for(let r of e)this.b.ids.add(r.body.id)}})}async prepare(t){try{this.ready=t.length&&JSON.stringify(t).length<4e4?await this.b.req(t):null}catch{this.ready=null}}flush(){let t=this.ready;this.ready=null,!(!t||this.problem||typeof t[1].body!="string"||t[1].body.length>64e3)&&(this.o.fetch??fetch)(t[0],{...t[1],keepalive:!0}).catch(()=>{})}async roll(){this.rolling=!0;try{await S(Math.random()*3e4,this.o.signal),await this.guarded(async()=>{if(await this.poll(),!this.b.big||!this.b.roll)return;let e=(await this.b.roll(this.o.allowed())).flatMap(r=>r.ops);e.length&&this.deliver(e)})}catch{}finally{this.rolling=!1}}};async function De(n,t){let e=tt(t.share,t.local);if(e.kind==="off")throw new Error(e.reason);let r=K(n.id,e.key),i=t.fetch??((h,T)=>fetch(h,T)),o=e.kind==="mailbox"?new $(e,r,i,t.signal):new C(e,r,i,t.signal),s=new Set,d=t.sendable??(h=>s.has(h.body.id)||h.body.author===n.me),a=t.signal??new AbortController().signal,l=new z(o,{signal:a,gap:t.gap??1e4,lock:!1,allowed:()=>n.ops().filter(d),changed(){}}),u=new O({id:"share",document:n,merge:async h=>{let T=await n.merge(h,"share"),N=new Set(n.ops().map(b=>b.body.id));for(let b of P(h))N.has(b)&&s.add(b);return T},transport:l,sendable:d,signal:a,delay:t.delay??0,gap:()=>l.gap});return await u.start(),{problem:()=>l.problem,waiting:()=>u.waiting,stop:()=>u.stop(),flush:async(h=12e4)=>(await l.poll(),new Promise((T,N)=>{let b=Date.now(),it=setInterval(j,250),ot=u.onState(j);function q(X){clearInterval(it),ot(),X?N(X):T()}function j(){if(l.problem)return q(new Error(`sharing stopped: the shared copy is ${l.problem==="gone"?"gone":l.problem==="full"?"full":"refusing this page"}`));if(!u.waiting&&u.state!=="sending")return q();Date.now()-b>h&&q(new Error("timed out before everything was sent"))}u.rescan(),j()}))}}export{De as connectShare};
package/dist/share.min.js CHANGED
@@ -1 +1 @@
1
- "use strict";(()=>{function X(n){let t=globalThis;(t.pipeupAddons||=[]).push(n),typeof addEventListener=="function"&&addEventListener("load",()=>{t.Pipeup||console.error(`pipeup: the "${n.id}" add-on needs Pipeup on the page too; load pipeup.min.js.`)},{once:!0})}var f=n=>new TextEncoder().encode(n),Y=n=>new TextDecoder().decode(n);function v(n){let t="";for(let e=0;e<n.length;e+=32768)t+=String.fromCharCode(...n.subarray(e,e+32768));return btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function y(n){let t=n.replace(/-/g,"+").replace(/_/g,"/"),e=atob(t+"=".repeat((4-t.length%4)%4));return Uint8Array.from(e,r=>r.charCodeAt(0))}function S(n){let t="";for(let e=0;e<n.length;e+=32768)t+=String.fromCharCode(...n.subarray(e,e+32768));return btoa(t)}function V(n){return Uint8Array.from(atob(n),t=>t.charCodeAt(0))}var P=n=>crypto.getRandomValues(new Uint8Array(n));async function L(n){return new Uint8Array(await crypto.subtle.digest("SHA-256",n))}var xe=/^([A-Za-z0-9_-]{16}):([A-Za-z0-9_-]{43})$/;function W(n,t=document){let e=xe.exec(t.documentElement.getAttribute("data-pipeup-doc")?.trim()??"");return e&&e[1]===n?y(e[2]):null}var Se=n=>f(`pipeup/v1/doc:${n}`);async function ce(n,t,e,r){let i=await crypto.subtle.importKey("raw",n,"HKDF",!1,["deriveBits"]);return crypto.subtle.deriveBits({name:"HKDF",hash:"SHA-256",salt:Se(t),info:f(e)},i,r)}function Q(n,t){return{docId:n,key:async e=>crypto.subtle.importKey("raw",await ce(t,n,`pipeup/v1/${e}/key`,256),"AES-GCM",!1,["encrypt","decrypt"]),addr:async e=>v(new Uint8Array(await ce(t,n,`pipeup/v1/${e}/address`,128))),aad:e=>`pipeup/v1/${e}:${n}`}}var Pe=1e6,Te=1e3;async function le(n,t,e=1/0){let r=new Blob([n]).stream().pipeThrough(t).getReader(),i=[],o=0;for(;;){let{done:d,value:c}=await r.read();if(d)break;if(o+=c.length,o>e)throw r.cancel(),new Error("too large");i.push(c)}let s=new Uint8Array(o),a=0;for(let d of i)s.set(d,a),a+=d.length;return s}var A=(n,t,e)=>D(n,t,{pipeup:1,doc:n.docId,sealed:!1,ops:e});async function D(n,t,e){let r=f(JSON.stringify(e)),i=P(12),o=await crypto.subtle.encrypt({name:"AES-GCM",iv:i,additionalData:f(n.aad(t))},await n.key(t),await le(r,new CompressionStream("deflate-raw"))),s=new Uint8Array(13+o.byteLength);return s[0]=1,s.set(i,1),s.set(new Uint8Array(o),13),s}async function I(n,t,e){try{if(e.length<29||e[0]!==1)return null;let r=await crypto.subtle.decrypt({name:"AES-GCM",iv:e.slice(1,13),additionalData:f(n.aad(t))},await n.key(t),e.slice(13));return JSON.parse(Y(await le(new Uint8Array(r),new DecompressionStream("deflate-raw"),Pe)))}catch{return null}}function C(n,t){let e=t;if(e?.pipeup!==1||e.doc!==n.docId||!Array.isArray(e.ops)||e.ops.length>Te)return null;let r=0;for(let i of e.ops){let o=i?.body?.v;typeof o=="number"&&o!==1&&r++}return{ops:e.ops,newer:r}}async function ee(n,t,e){return C(n,await I(n,t,e))}var te=n=>`pu1.${v(n)}`,ne=n=>{if(!/^pu1\.[A-Za-z0-9_-]+$/.test(n))return null;try{return y(n.slice(4))}catch{return null}};async function re(n,t={}){let e=new Map,r={get:async i=>e.get(i),set:async(i,o)=>void e.set(i,o),lasting:!1};if(t.memory||typeof indexedDB>"u")return r;try{let i=await new Promise((s,a)=>{let d=setTimeout(()=>a(new Error("timed out")),4e3),c=indexedDB.open(`pipeup-addon-${n}`,1);c.onupgradeneeded=()=>c.result.createObjectStore("kv"),c.onsuccess=()=>{clearTimeout(d),s(c.result)},c.onerror=c.onblocked=()=>{clearTimeout(d),a(c.error??new Error("blocked"))}}),o=(s,a)=>new Promise((d,c)=>{let m=a(i.transaction("kv",s).objectStore("kv"));m.onsuccess=()=>d(m.result),m.onerror=()=>c(m.error)});return{get:s=>o("readonly",a=>a.get(s)),set:async(s,a)=>void await o("readwrite",d=>d.put(a,s)),lasting:!0}}catch{return r}}var h=class extends Error{constructor(e,r=!1){super(`try again in ${e} s`);this.seconds=e;this.limit=r;this.name="RetryAfter"}};var Oe=100,pe=5e3,Be=5e3,Ue=3e5,_e=3600,E=class{constructor(t){this.o=t}state="idle";lastOk=0;known=new Set;outbox=new Map;rejected=new Set;inbound=[];inboundTimer=0;sendTimer=0;lastSend=0;backoff=0;off=null;listeners=new Set;stopped=!1;get waiting(){return this.outbox.size}pending(){return[...this.outbox.values()]}onState(t){return this.listeners.add(t),()=>this.listeners.delete(t)}emit(t){t&&(this.state=t);for(let e of[...this.listeners])e()}async start(){let{document:t,transport:e,signal:r}=this.o;this.off=t.onChange((o,s,a)=>{if(a===this.o.id)return;let d=!1;for(let c of s)this.want(c)&&(d=this.outbox.set(c.body.id,c).size>0||d);d&&this.schedule(),this.emit()}),r.addEventListener("abort",()=>this.stop(),{once:!0}),await e.start(o=>this.deliver(o));let i=await e.remoteIds?.();if(i)for(let o of i)this.known.add(o);this.rescan()}stop(){this.stopped||(this.stopped=!0,this.off?.(),clearTimeout(this.inboundTimer),clearTimeout(this.sendTimer),this.o.transport.stop())}want(t){return!this.known.has(t.body.id)&&!this.rejected.has(t.body.id)&&this.o.sendable(t)}rescan(){this.outbox.clear();for(let t of this.o.document.ops())this.want(t)&&this.outbox.set(t.body.id,t);this.schedule(),this.emit()}deliver(t){this.inbound.push(...t),this.inboundTimer||(this.inboundTimer=setTimeout(()=>void this.drain(),Oe))}async drain(){this.inboundTimer=0;let t=this.inbound.splice(0),e=t.map(i=>i?.body?.id).filter(i=>typeof i=="string");for(let i=0;i<t.length;i+=pe)try{await this.o.merge(t.slice(i,i+pe))}catch(o){o?.name!=="UnsavedChangeError"&&globalThis.reportError?.(o)}let r=new Set(this.o.document.ops().map(i=>i.body.id));for(let i of e)r.has(i)?(this.known.add(i),this.outbox.delete(i)):this.rejected.add(i);this.lastOk=Date.now(),this.emit()}schedule(t=this.o.delay??0){if(this.stopped||this.sendTimer||this.outbox.size===0)return;let e=typeof this.o.gap=="function"?this.o.gap():this.o.gap??0,r=Math.max(t,this.lastSend+e-Date.now(),this.backoff);this.sendTimer=setTimeout(()=>void this.send(),r)}async send(){if(this.sendTimer=0,this.stopped||this.o.signal.aborted||this.outbox.size===0)return;let t=[...this.outbox.values()].slice(0,this.o.batch??500);this.emit("sending");try{await this.o.transport.send(t);for(let e of t)this.known.add(e.body.id),this.outbox.delete(e.body.id);this.lastSend=Date.now(),this.lastOk=this.lastSend,this.backoff=0,this.emit("idle")}catch(e){e instanceof h?(this.backoff=Math.min(e.seconds,_e)*1e3*(1+Math.random()*.2),this.emit("limited")):(this.backoff=Math.min(Ue,this.backoff?this.backoff*2:Be),this.emit("offline"))}this.schedule()}};var dt=2n**256n-2n**32n-977n;var Me="sharing isn't set up for this page",M="data-pipeup-share isn't a sharing address",$e=/^(localhost|127\.0\.0\.1|\[::1\])$/,he=/^[A-Za-z0-9_-]{43}$/,T=n=>({kind:"off",reason:n});function ue(n,t=!1){let e=n?.trim();if(!e)return T(Me);let r;try{r=new URL(e)}catch{return T(M)}if(r.protocol!=="https:"&&!(t&&r.protocol==="http:"&&$e.test(r.hostname)))return T(M);let i=r.origin+r.pathname,o=r.hash.slice(1);if(o.startsWith("pm1.")){let[a,d,...c]=o.slice(4).split(".");return!he.test(a??"")||c.length||d!==void 0&&!/^[A-Za-z0-9_-]+$/.test(d)||r.search||!/\/m\/[A-Za-z0-9_-]{22,64}$/.test(i)?T(M):{kind:"mailbox",mailbox:i,key:y(a),...d?{token:d}:{}}}let s=/^\?([A-Za-z0-9_-]{8,64})$/.exec(r.search)?.[1];return!s||!he.test(o)?T(M):{kind:"privatebin",base:i,paste:s,key:y(o)}}var g=class extends Error{constructor(e){super(e);this.kind=e;this.name="Problem"}},fe={Accept:"application/json"},N=(n,t,e)=>n(t,{headers:fe,credentials:"omit",signal:e}),O=n=>({method:"POST",headers:fe,credentials:"omit",body:JSON.stringify(n)}),me=n=>{let t={403:"closed",404:"gone",507:"full"}[n];return t&&new g(t)};async function B(n){let t=await n.text(),e=t.length<1e7&&JSON.parse(t);if(!e||typeof e!="object")throw new Error("the answer was not usable");return[e,t.length]}function $(n,t=9e5){let e=[],r=0;for(let i of n)r+=JSON.stringify(i).length,(!e.length||r>t||e.at(-1).length>=500)&&(e.push([]),r=JSON.stringify(i).length),e.at(-1).push(i);return e}var U=(n,t)=>new Promise(e=>{let r=setTimeout(e,n);t?.addEventListener("abort",()=>{clearTimeout(r),e()},{once:!0})}),z=(n,t=10)=>{let e=Number(n.headers.get("Retry-After"));return e>0?Math.min(e,3600):t},_=n=>n.map(t=>t?.body?.id).filter(t=>typeof t=="string");var Re=524288,Le=1e3,De=async n=>v(await L(f(n))).slice(0,22),j=class{constructor(t,e,r,i){this.a=t;this.l=e;this.f=r;this.signal=i}ids=new Set;expires=null;moved=!1;big=!1;cursor="";seen=new Set;memo=null;async read(){let t=[],e=0;for(let r=0;r<Le;){let i=`${this.a.mailbox}/ops${this.cursor?`?since=${encodeURIComponent(this.cursor)}`:""}`,o=await N(this.f,i,this.signal);if(o.status===404)throw new g("gone");if(o.status===409&&e++<2){this.cursor="";continue}if(!o.ok)throw new Error(`HTTP ${o.status}`);r++;let[s]=await B(o);for(let a of Array.isArray(s.batches)?s.batches:[]){if(typeof a?.id!="string"||typeof a.ct!="string"||this.seen.has(a.id))continue;this.seen.add(a.id);let d=ne(a.ct),c=d&&await ee(this.l,"share",d);if(c){t.push(c);for(let m of _(c.ops))this.ids.add(m)}}if(typeof s.next=="string"&&(this.cursor=s.next),this.expires=typeof s.expires=="string"&&Date.parse(s.expires)||null,s.more!==!0)break}return t}async req(t){let e=t.map(o=>o.body.id).join();if(this.memo?.key!==e){let o=te(await A(this.l,"share",t));this.memo={key:e,ct:o,id:await De(o)}}let{ct:r,id:i}=this.memo;return[`${this.a.mailbox}/ops`,O({id:i,ct:r,token:this.a.token})]}async post(t){for(let e of $(t))await this.one(e)}async one(t){let[e,r]=await this.req(t),i=async()=>{let d=t.length>>1;await this.one(t.slice(0,d)),await this.one(t.slice(d))};if(r.body.length>Re&&t.length>1)return i();let o=await this.f(e,{...r,signal:this.signal}),s=o.status;if(s===200||s===201||s===400)return;if(s===413&&t.length>1)return i();let a=me(s);if(a)throw a;if(s===429){let[d]=await B(o).catch(()=>[{}]),c=Number(d.retryAfter);throw new h(o.headers.get("Retry-After")?z(o):c>0?Math.min(c,3600):10)}throw new Error(`HTTP ${s}`)}};var H=class{constructor(t,e){this.me=t;this.held=new Set(e?.held),this.kept=new Set(e?.kept),this.recv=new Set(e?.recv),this.send=e?.send??!0,this.noted=e?.noted??!1,this.gen=e?.gen??null,this.init=e?.init??!1}held;kept;recv;send;noted;gen;init;hold(t){if(!this.init){this.init=!0;for(let{body:e}of t)e.author===this.me&&this.held.add(e.id)}}sendable(t){let e=t.body;if(this.recv.has(e.id))return!0;if(e.author!==this.me||this.held.has(e.id)||this.kept.has(e.id))return!1;let r=[e.target,e.thread].find(i=>i&&(this.held.has(i)||this.kept.has(i)));if(r)(this.held.has(r)?this.held:this.kept).add(e.id);else if(!this.send)this.kept.add(e.id);else return(e.kind==="create"||e.kind==="reply")&&(this.noted=!0),!0;return!1}decide(t){if(!t)for(let e of this.held)this.kept.add(e);this.held.clear()}};var Ie=256e3,Ce=16,Ne=/^[A-Za-z0-9_-]{8,64}$/,ge=()=>[S(P(16)),S(P(8)),1e5,256,128,"aes","gcm","none"],ze=(n,t)=>({v:2,adata:ge(),ct:S(t),pasteid:n,parentid:n});async function q(n){if(n.status===429)throw new h(z(n));if(!n.ok)throw new Error(`HTTP ${n.status}`);let[t]=await B(n);if(t.status===0)return t;let e=Number(/\d+/.exec(String(t.message??""))?.[0]);throw new h(e>=1&&e<=3600?e:30,!0)}async function je(n,t,e,r="never",i){let o=S(await A(e,"share",[])),s=await q(await n(t,{...O({v:2,adata:[ge(),"plaintext",1,0],ct:o,meta:{expire:r}}),signal:i}));if(typeof s.id!="string"||typeof s.deletetoken!="string")throw new Error("the answer had no paste id");return{id:s.id,deleteToken:s.deletetoken}}async function He(n,t,e,r){return n(t,O({pasteid:e,deletetoken:r}))}async function qe(n,t,e,r){let i=await N(n,`${t}?${e}`,r);if(i.status===404)return null;if(!i.ok)throw new Error(`HTTP ${i.status}`);let[o,s]=await B(i);if(o.status!==0)return null;let a=o.meta?.time_to_live;return{j:o,size:s,ttl:typeof a=="number"&&a>0?a*1e3:null}}var F=class{constructor(t,e,r,i,o,s=()=>{}){this.a=t;this.l=e;this.f=r;this.signal=i;this.onGen=s;this.head=o||t.paste,this.trail.push(t.paste)}ids=new Set;expires=null;moved=!1;big=!1;head;trail=[];seen=new Map;async scan(t,e){let r;for(let i of Array.isArray(t)?t:[]){if(typeof i?.id!="string"||typeof i.ct!="string")continue;let o=this.seen.get(i.id);if(o===void 0){o=null;let s=null;try{i.ct.length<14e5&&(s=V(i.ct))}catch{}let a=s&&await I(this.l,"share",s),d=a?.next,c=typeof d=="string"?null:C(this.l,a);if(typeof d=="string"&&Ne.test(d))o=d;else if(c){e.push(c);for(let m of _(c.ops))this.ids.add(m)}this.seen.set(i.id,o)}r??=o??void 0}return r}async read(){let t=[],e=this.head,r=!1,i=!1;for(let o=0;;){let s=await qe(this.f,this.a.base,e,this.signal);if(!s){if(i)break;if(!r&&e!==this.a.paste){r=!0,e=this.a.paste;continue}throw new g("gone")}i=!0,e!==this.head&&(this.head=e,this.trail.push(e),this.ids.clear(),this.moved=!0,this.onGen(e));let a=s.j.comments,d=await this.scan(a,t);this.expires=s.ttl&&Date.now()+s.ttl;let c=(Array.isArray(a)?a[0]?.ct?.length:0)??0;if(this.big=!d&&s.size>Ie&&s.size>2*c,!d||++o>=Ce)break;e=d}return t}ask(t,e){return[this.a.base,O(ze(t,e))]}async req(t){return this.ask(this.head,await A(this.l,"share",t))}go(t,e){return this.f(t,{...e,signal:this.signal})}async post(t){for(let e of $(t))await q(await this.go(...await this.req(e)))}async roll(t){let e=async s=>{for(let a=0;;a++)try{return await s()}catch(d){if(!(d instanceof h)||a>5||this.signal?.aborted)throw d;await U(d.seconds*1e3*(1+Math.random()*.2),this.signal)}},r=this.head,i=await e(()=>je(this.f,this.a.base,this.l,"never",this.signal));for(let s of $(t))await e(async()=>q(await this.go(...this.ask(i.id,await A(this.l,"share",s)))));await e(async()=>q(await this.go(...this.ask(r,await D(this.l,"share",{next:i.id})))));let o=await this.read();return this.head!==i.id&&await He(this.f,this.a.base,i.id,i.deleteToken).catch(()=>{}),o}};function Fe(n,t,e,r=Math.random()){let i=t?3e5:n<6e5?25e3+r*1e4:n<18e5?12e4:3e5;return Math.min(3e5,i*2**e)}var K=class{constructor(t,e){this.b=t;this.o=e}id="share";problem=null;offline=!1;newer=0;deliver=()=>{};active=Date.now();errors=0;ok=!1;timer;busy=null;again=!1;limit=0;rolling=!1;ready=null;stopped=!1;off=[];async start(t){this.deliver=t;let e=(i,o,s)=>{i&&(i.addEventListener(o,s),this.off.push(()=>i.removeEventListener(o,s)))},r=globalThis;r.addEventListener&&(e(globalThis,"focus",()=>void this.poll()),e(globalThis,"online",()=>void this.poll()),e(globalThis,"pagehide",()=>this.flush()),e(r.document,"visibilitychange",()=>r.document?.visibilityState==="visible"&&void this.poll())),await this.poll()}stop(){this.stopped=!0,clearTimeout(this.timer);for(let t of this.off.splice(0))t()}async remoteIds(){return this.ok?this.b.ids:null}poll(){if(this.busy)return this.again=!0,this.busy;let t=async()=>{do this.again=!1,await this.read();while(this.again&&!this.stopped)};return this.busy=t().finally(()=>this.busy=null)}bump(){this.active=Date.now()}async read(){clearTimeout(this.timer);try{let t=await this.b.read();this.offline=!1,this.errors=0,this.ok=!0,this.newer+=t.reduce((r,i)=>r+i.newer,0);let e=t.flatMap(r=>r.ops);if(e.length&&(this.active=Date.now(),this.deliver(e)),this.b.moved){this.b.moved=!1;let r=this.o.allowed().filter(i=>!this.b.ids.has(i.body.id));r.length&&await this.b.post(r).catch(()=>{})}this.b.big&&!this.rolling&&this.roll()}catch(t){t instanceof g?this.problem=t.kind:(this.offline=!0,this.errors++)}if(this.o.changed(),!this.stopped&&this.problem!=="gone"){let t=globalThis.document?.visibilityState==="hidden";this.timer=setTimeout(()=>void this.poll(),Fe(Date.now()-this.active,t,this.errors))}}lock(t,e=0){let r=this.o.lock,i=globalThis.navigator?.locks;return r?i?new Promise((o,s)=>{i.request(r,{signal:this.o.signal},async()=>{try{o(await t())}catch(a){s(a)}await U(e,this.o.signal)}).catch(s)}):U(Math.random()*5e3,this.o.signal).then(t):t()}get gap(){return Math.max(this.o.gap,this.limit)}async guarded(t){try{await this.lock(t,this.gap),this.offline=!1}catch(e){throw e instanceof h?(e.limit&&(this.limit=Math.max(this.limit,e.seconds*1e3)),e):e instanceof g?(this.problem=e.kind,this.o.changed(),new h(3600)):(this.offline=!0,this.o.changed(),e)}}async send(t){if(this.problem)throw new h(3600);this.bump(),await this.guarded(async()=>{await this.poll();let e=t.filter(r=>!this.b.ids.has(r.body.id));if(e.length){await this.b.post(e);for(let r of e)this.b.ids.add(r.body.id)}})}async prepare(t){try{this.ready=t.length&&JSON.stringify(t).length<4e4?await this.b.req(t):null}catch{this.ready=null}}flush(){let t=this.ready;this.ready=null,!(!t||this.problem||typeof t[1].body!="string"||t[1].body.length>64e3)&&(this.o.fetch??fetch)(t[0],{...t[1],keepalive:!0}).catch(()=>{})}async roll(){this.rolling=!0;try{await U(Math.random()*3e4,this.o.signal),await this.guarded(async()=>{if(await this.poll(),!this.b.big||!this.b.roll)return;let e=(await this.b.roll(this.o.allowed())).flatMap(r=>r.ops);e.length&&this.deliver(e)})}catch{}finally{this.rolling=!1}}};var Ke="Comments here are shared with everyone who has this page.",Ge=7*864e5,ye=["M12 16V4M7 9l5-5 5 5M5 20h14"],Je=["M7 11V8a5 5 0 0 1 10 0v3M6 11h12v9H6z"];function be(n={}){return{id:"share",api:1,version:"0.4.1",needs:["sync","menu","notify","note"],network:{when:"page-configured",to:["page"],says:"Sends the comments you choose to share, sealed so only people with this page can read them, to the sharing service the page names. That service sees when and how much is sent, and your network address."},async setup(t){let e=t.document,r=ue(n.share??document.documentElement.getAttribute("data-pipeup-share"),!0);if(r.kind==="off")return t.off(r.reason);if(!W(e.id))return t.off("needs a document identity");let i=Q(e.id,r.key),o=await re("share",{memory:t.ephemeral}),s=await o.get(`doc:${e.id}`),a=new H(e.me,s);a.hold(e.ops());let d=Promise.resolve(),c=()=>{d=d.then(()=>o.set(`doc:${e.id}`,{...a})).catch(()=>{})};c();let m={gone:"The shared copy is gone",closed:"This page can't send to the shared copy; ask the author for the current file",full:"The shared copy is full; the author can start it again"},ie=new Set,oe=(l,u)=>ie.has(l)||(ie.add(l),t.notify(u)),x=()=>{for(let l of R)l.update();t.setStatus({text:de()}),t.setComposerNote(a.send&&!a.noted&&p.problem!=="gone"?Ke:null),p.newer&&oe("newer",`${p.newer} comments come from a newer version of Pipeup; this page can't show them yet.`),p.problem&&oe(p.problem,m[p.problem]+(p.problem==="gone"?". Your comments stay on this machine.":"."))},se=(l,u)=>fetch(l,u),ae=r.kind==="mailbox"?new j(r,i,se,t.signal):new F(r,i,se,t.signal,a.gen,l=>{a.gen=l,c()}),p=new K(ae,{signal:t.signal,gap:1e4,lock:`pipeup-share:${e.id}`,allowed:()=>e.ops().filter(l=>a.sendable(l)),changed:x}),b=new E({id:"share",document:e,merge:async l=>{let u=await t.merge(l),k=new Set(e.ops().map(w=>w.body.id));for(let w of _(l))k.has(w)&&a.recv.add(w);return c(),u},transport:p,sendable:l=>{let u=a.sendable(l);return a.noted!==s?.noted&&c(),u},signal:t.signal,delay:2e3,gap:()=>p.gap}),G;b.onState(()=>{x(),clearTimeout(G),G=setTimeout(()=>void p.prepare(b.pending()),1e3)});let we=new URL(r.kind==="mailbox"?r.mailbox:r.base).host,de=()=>{let l=b.waiting;return p.problem?m[p.problem]:a.send?p.offline||b.state==="offline"?"Shared \xB7 offline, sends when back":l?`Shared \xB7 ${l} change${l===1?"":"s"} waiting`:"Shared \xB7 up to date":"Shared \xB7 not sending your comments"},ve=()=>{let l=ae.expires;return p.problem==="gone"?"Your comments stay on this machine. The author can start sharing again.":[`Your comments are encrypted and sent to ${we} so others with this page see them. The service can't read them. People who already have your comments, by file or live, could pass them on.`,t.ephemeral&&"This browser can't keep comments; the shared copy keeps the ones you send.",!o.lasting&&"This browser won't remember this choice.",l&&l-Date.now()<Ge&&`The shared copy expires on ${new Date(l).toLocaleDateString("en-GB",{day:"numeric",month:"long"})}.`].filter(Boolean).join(" ")},R=[],J=(l,u,k,w,ke,Ae)=>R[R.push(t.addMenuItem({id:l,icon:u,label:k,hint:w,select:ke,checked:Ae}))-1],Z=e.ops().filter(l=>a.held.has(l.body.id)&&(l.body.kind==="create"||l.body.kind==="reply")).length;if(J("send",ye,()=>a.send||p.problem?de():"Send my comments",ve,()=>{a.send=!a.send,c(),b.rescan(),x()},()=>a.send),Z){let l=o.lasting?"":" This browser won't remember this choice.",u=k=>()=>{a.decide(k),c();for(let w of R.splice(1))w.remove();b.rescan(),x()};J("share-earlier",ye,()=>`Share my ${Z} earlier comment${Z===1?"":"s"}`,()=>`Send the comments you wrote before this page was shared.${l}`,u(!0)),J("keep-earlier",Je,()=>"Keep them on this machine",()=>`Never send the comments you wrote before this page was shared.${l}`,u(!1))}return x(),b.start().then(x,l=>globalThis.reportError?.(l)),e.onChange((l,u,k)=>{k==="local"&&u.length&&p.bump()}),()=>{clearTimeout(G),b.stop()}}}}X(be());})();
1
+ "use strict";(()=>{function W(n){let t=globalThis;(t.pipeupAddons||=[]).push(n),typeof addEventListener=="function"&&addEventListener("load",()=>{t.Pipeup||console.error(`pipeup: the "${n.id}" add-on needs Pipeup on the page too; load pipeup.min.js.`)},{once:!0})}var S=(n,t)=>t?t.getAttribute(n):globalThis.Pipeup?.setting?.(n)??globalThis.document?.documentElement.getAttribute(n)??null;var m=n=>new TextEncoder().encode(n),V=n=>new TextDecoder().decode(n);function k(n){let t="";for(let e=0;e<n.length;e+=32768)t+=String.fromCharCode(...n.subarray(e,e+32768));return btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function w(n){let t=n.replace(/-/g,"+").replace(/_/g,"/"),e=atob(t+"=".repeat((4-t.length%4)%4));return Uint8Array.from(e,r=>r.charCodeAt(0))}function P(n){let t="";for(let e=0;e<n.length;e+=32768)t+=String.fromCharCode(...n.subarray(e,e+32768));return btoa(t)}function Q(n){return Uint8Array.from(atob(n),t=>t.charCodeAt(0))}var T=n=>crypto.getRandomValues(new Uint8Array(n));async function D(n){return new Uint8Array(await crypto.subtle.digest("SHA-256",n))}var Oe=/^([A-Za-z0-9_-]{16}):([A-Za-z0-9_-]{43})$/;function ee(n,t=document){let e=Oe.exec((t===globalThis.document?S("data-pipeup-doc"):t.documentElement.getAttribute("data-pipeup-doc"))?.trim()??"");return e&&e[1]===n?w(e[2]):null}var Be=n=>m(`pipeup/v1/doc:${n}`);async function he(n,t,e,r){let i=await crypto.subtle.importKey("raw",n,"HKDF",!1,["deriveBits"]);return crypto.subtle.deriveBits({name:"HKDF",hash:"SHA-256",salt:Be(t),info:m(e)},i,r)}function te(n,t){return{docId:n,key:async e=>crypto.subtle.importKey("raw",await he(t,n,`pipeup/v1/${e}/key`,256),"AES-GCM",!1,["encrypt","decrypt"]),addr:async e=>k(new Uint8Array(await he(t,n,`pipeup/v1/${e}/address`,128))),aad:e=>`pipeup/v1/${e}:${n}`}}var Ee=1e6,Ue=1e3;async function ue(n,t,e=1/0){let r=new Blob([n]).stream().pipeThrough(t).getReader(),i=[],o=0;for(;;){let{done:d,value:l}=await r.read();if(d)break;if(o+=l.length,o>e)throw r.cancel(),new Error("too large");i.push(l)}let s=new Uint8Array(o),a=0;for(let d of i)s.set(d,a),a+=d.length;return s}var A=(n,t,e)=>L(n,t,{pipeup:1,doc:n.docId,sealed:!1,ops:e});async function L(n,t,e){let r=m(JSON.stringify(e)),i=T(12),o=await crypto.subtle.encrypt({name:"AES-GCM",iv:i,additionalData:m(n.aad(t))},await n.key(t),await ue(r,new CompressionStream("deflate-raw"))),s=new Uint8Array(13+o.byteLength);return s[0]=1,s.set(i,1),s.set(new Uint8Array(o),13),s}async function C(n,t,e){try{if(e.length<29||e[0]!==1)return null;let r=await crypto.subtle.decrypt({name:"AES-GCM",iv:e.slice(1,13),additionalData:m(n.aad(t))},await n.key(t),e.slice(13));return JSON.parse(V(await ue(new Uint8Array(r),new DecompressionStream("deflate-raw"),Ee)))}catch{return null}}function N(n,t){let e=t;if(e?.pipeup!==1||e.doc!==n.docId||!Array.isArray(e.ops)||e.ops.length>Ue)return null;let r=0;for(let i of e.ops){let o=i?.body?.v;typeof o=="number"&&o!==1&&r++}return{ops:e.ops,newer:r}}async function ne(n,t,e){return N(n,await C(n,t,e))}var re=n=>`pu1.${k(n)}`,ie=n=>{if(!/^pu1\.[A-Za-z0-9_-]+$/.test(n))return null;try{return w(n.slice(4))}catch{return null}};async function oe(n,t={}){let e=new Map,r={get:async i=>e.get(i),set:async(i,o)=>void e.set(i,o),lasting:!1};if(t.memory||typeof indexedDB>"u")return r;try{let i=await new Promise((s,a)=>{let d=setTimeout(()=>a(new Error("timed out")),4e3),l=indexedDB.open(`pipeup-addon-${n}`,1);l.onupgradeneeded=()=>l.result.createObjectStore("kv"),l.onsuccess=()=>{clearTimeout(d),s(l.result)},l.onerror=l.onblocked=()=>{clearTimeout(d),a(l.error??new Error("blocked"))}}),o=(s,a)=>new Promise((d,l)=>{let f=a(i.transaction("kv",s).objectStore("kv"));f.onsuccess=()=>d(f.result),f.onerror=()=>l(f.error)});return{get:s=>o("readonly",a=>a.get(s)),set:async(s,a)=>void await o("readwrite",d=>d.put(a,s)),lasting:!0}}catch{return r}}var u=class extends Error{constructor(e,r=!1){super(`try again in ${e} s`);this.seconds=e;this.limit=r;this.name="RetryAfter"}};var _e=100,fe=5e3,Me=5e3,Re=3e5,$e=3600,M=class{constructor(t){this.o=t}state="idle";lastOk=0;known=new Set;outbox=new Map;rejected=new Set;inbound=[];inboundTimer=0;sendTimer=0;lastSend=0;backoff=0;off=null;listeners=new Set;stopped=!1;get waiting(){return this.outbox.size}pending(){return[...this.outbox.values()]}onState(t){return this.listeners.add(t),()=>this.listeners.delete(t)}emit(t){t&&(this.state=t);for(let e of[...this.listeners])e()}async start(){let{document:t,transport:e,signal:r}=this.o;this.off=t.onChange((o,s,a)=>{if(a===this.o.id)return;let d=!1;for(let l of s)this.want(l)&&(d=this.outbox.set(l.body.id,l).size>0||d);d&&this.schedule(),this.emit()}),r.addEventListener("abort",()=>this.stop(),{once:!0}),await e.start(o=>this.deliver(o));let i=await e.remoteIds?.();if(i)for(let o of i)this.known.add(o);this.rescan()}stop(){this.stopped||(this.stopped=!0,this.off?.(),clearTimeout(this.inboundTimer),clearTimeout(this.sendTimer),this.o.transport.stop())}want(t){return!this.known.has(t.body.id)&&!this.rejected.has(t.body.id)&&this.o.sendable(t)}rescan(){this.outbox.clear();for(let t of this.o.document.ops())this.want(t)&&this.outbox.set(t.body.id,t);this.schedule(),this.emit()}deliver(t){this.inbound.push(...t),this.inboundTimer||(this.inboundTimer=setTimeout(()=>void this.drain(),_e))}async drain(){this.inboundTimer=0;let t=this.inbound.splice(0),e=t.map(i=>i?.body?.id).filter(i=>typeof i=="string");for(let i=0;i<t.length;i+=fe)try{await this.o.merge(t.slice(i,i+fe))}catch(o){o?.name!=="UnsavedChangeError"&&globalThis.reportError?.(o)}let r=new Set(this.o.document.ops().map(i=>i.body.id));for(let i of e)r.has(i)?(this.known.add(i),this.outbox.delete(i)):this.rejected.add(i);this.lastOk=Date.now(),this.emit()}schedule(t=this.o.delay??0){if(this.stopped||this.sendTimer||this.outbox.size===0)return;let e=typeof this.o.gap=="function"?this.o.gap():this.o.gap??0,r=Math.max(t,this.lastSend+e-Date.now(),this.backoff);this.sendTimer=setTimeout(()=>void this.send(),r)}async send(){if(this.sendTimer=0,this.stopped||this.o.signal.aborted||this.outbox.size===0)return;let t=[...this.outbox.values()].slice(0,this.o.batch??500);this.emit("sending");try{await this.o.transport.send(t);for(let e of t)this.known.add(e.body.id),this.outbox.delete(e.body.id);this.lastSend=Date.now(),this.lastOk=this.lastSend,this.backoff=0,this.emit("idle")}catch(e){e instanceof u?(this.backoff=Math.min(e.seconds,$e)*1e3*(1+Math.random()*.2),this.emit("limited")):(this.backoff=Math.min(Re,this.backoff?this.backoff*2:Me),this.emit("offline"))}this.schedule()}};var yt=2n**256n-2n**32n-977n;var De="sharing isn't set up for this page",R="data-pipeup-share isn't a sharing address",Le=/^(localhost|127\.0\.0\.1|\[::1\])$/,me=/^[A-Za-z0-9_-]{43}$/,O=n=>({kind:"off",reason:n});function ge(n,t=!1){let e=n?.trim();if(!e)return O(De);let r;try{r=new URL(e)}catch{return O(R)}if(r.protocol!=="https:"&&!(t&&r.protocol==="http:"&&Le.test(r.hostname)))return O(R);let i=r.origin+r.pathname,o=r.hash.slice(1);if(o.startsWith("pm1.")){let[a,d,...l]=o.slice(4).split(".");return!me.test(a??"")||l.length||d!==void 0&&!/^[A-Za-z0-9_-]+$/.test(d)||r.search||!/\/m\/[A-Za-z0-9_-]{22,64}$/.test(i)?O(R):{kind:"mailbox",mailbox:i,key:w(a),...d?{token:d}:{}}}let s=/^\?([A-Za-z0-9_-]{8,64})$/.exec(r.search)?.[1];return!s||!me.test(o)?O(R):{kind:"privatebin",base:i,paste:s,key:w(o)}}var b=class extends Error{constructor(e){super(e);this.kind=e;this.name="Problem"}},ye={Accept:"application/json"},z=(n,t,e)=>n(t,{headers:ye,credentials:"omit",signal:e}),B=n=>({method:"POST",headers:ye,credentials:"omit",body:JSON.stringify(n)}),be=n=>{let t={403:"closed",404:"gone",507:"full"}[n];return t&&new b(t)};async function E(n){let t=await n.text(),e=t.length<1e7&&JSON.parse(t);if(!e||typeof e!="object")throw new Error("the answer was not usable");return[e,t.length]}function $(n,t=9e5){let e=[],r=0;for(let i of n)r+=JSON.stringify(i).length,(!e.length||r>t||e.at(-1).length>=500)&&(e.push([]),r=JSON.stringify(i).length),e.at(-1).push(i);return e}var U=(n,t)=>new Promise(e=>{let r=setTimeout(e,n);t?.addEventListener("abort",()=>{clearTimeout(r),e()},{once:!0})}),H=(n,t=10)=>{let e=Number(n.headers.get("Retry-After"));return e>0?Math.min(e,3600):t},_=n=>n.map(t=>t?.body?.id).filter(t=>typeof t=="string");var Ce=524288,Ne=1e3,ze=async n=>k(await D(m(n))).slice(0,22),j=class{constructor(t,e,r,i){this.a=t;this.l=e;this.f=r;this.signal=i}ids=new Set;expires=null;moved=!1;big=!1;cursor="";seen=new Set;memo=null;async read(){let t=[],e=0;for(let r=0;r<Ne;){let i=`${this.a.mailbox}/ops${this.cursor?`?since=${encodeURIComponent(this.cursor)}`:""}`,o=await z(this.f,i,this.signal);if(o.status===404)throw new b("gone");if(o.status===409&&e++<2){this.cursor="";continue}if(!o.ok)throw new Error(`HTTP ${o.status}`);r++;let[s]=await E(o);for(let a of Array.isArray(s.batches)?s.batches:[]){if(typeof a?.id!="string"||typeof a.ct!="string"||this.seen.has(a.id))continue;this.seen.add(a.id);let d=ie(a.ct),l=d&&await ne(this.l,"share",d);if(l){t.push(l);for(let f of _(l.ops))this.ids.add(f)}}if(typeof s.next=="string"&&(this.cursor=s.next),this.expires=typeof s.expires=="string"&&Date.parse(s.expires)||null,s.more!==!0)break}return t}async req(t){let e=t.map(o=>o.body.id).join();if(this.memo?.key!==e){let o=re(await A(this.l,"share",t));this.memo={key:e,ct:o,id:await ze(o)}}let{ct:r,id:i}=this.memo;return[`${this.a.mailbox}/ops`,B({id:i,ct:r,token:this.a.token})]}async post(t){for(let e of $(t))await this.one(e)}async one(t){let[e,r]=await this.req(t),i=async()=>{let d=t.length>>1;await this.one(t.slice(0,d)),await this.one(t.slice(d))};if(r.body.length>Ce&&t.length>1)return i();let o=await this.f(e,{...r,signal:this.signal}),s=o.status;if(s===200||s===201||s===400)return;if(s===413&&t.length>1)return i();let a=be(s);if(a)throw a;if(s===429){let[d]=await E(o).catch(()=>[{}]),l=Number(d.retryAfter);throw new u(o.headers.get("Retry-After")?H(o):l>0?Math.min(l,3600):10)}throw new Error(`HTTP ${s}`)}};var He=new Set(["reply","addressed","react","unreact"]),we=()=>(S("data-pipeup-agents")??"").split(/[\s,]+/).filter(Boolean),q=class{constructor(t,e,r=()=>[]){this.me=t;this.agents=r;this.held=new Set(e?.held),this.kept=new Set(e?.kept),this.recv=new Set(e?.recv),this.chosen=new Set(e?.chosen),this.follow=new Set(e?.follow),this.legacy=new Set(e?.legacy??(e?.init&&e.chosen===void 0?e.kept:void 0)),this.send=e?.send??!0,this.noted=e?.noted??!1,this.gen=e?.gen??null,this.init=e?.init??!1}held;kept;recv;chosen;follow;legacy;send;noted;gen;init;saved(){let{init:t,held:e,kept:r,recv:i,chosen:o,follow:s,legacy:a,send:d,noted:l,gen:f}=this;return{init:t,held:e,kept:r,recv:i,chosen:o,follow:s,legacy:a,send:d,noted:l,gen:f}}hold(t){if(!this.init){this.init=!0;for(let{body:e}of t)e.author===this.me&&this.held.add(e.id)}}sendable(t){let e=t.body;if(this.recv.has(e.id))return!0;if(He.has(e.kind)&&this.agents().includes(e.author))return this.send&&![e.target,e.thread].some(i=>i&&(this.held.has(i)||this.kept.has(i)));if(e.author!==this.me||this.held.has(e.id)||this.kept.has(e.id))return!1;let r=[e.target,e.thread].find(i=>i&&(this.held.has(i)||this.kept.has(i)));if(r)(this.held.has(r)?this.held:this.kept).add(e.id),this.follow.add(e.id);else if(!this.send)this.kept.add(e.id);else return(e.kind==="create"||e.kind==="reply")&&(this.noted=!0),!0;return!1}local(t){let e=t.body;return e.author!==this.me||this.recv.has(e.id)||!(this.held.has(e.id)||this.kept.has(e.id))?null:this.follow.has(e.id)?"thread":this.held.has(e.id)?"held":this.chosen.has(e.id)?"chosen":this.legacy.has(e.id)?"unknown":"kept"}decide(t){if(!t)for(let e of this.held)this.kept.add(e),this.chosen.add(e);this.held.clear()}};var je=256e3,qe=16,Fe=/^[A-Za-z0-9_-]{8,64}$/,ve=()=>[P(T(16)),P(T(8)),1e5,256,128,"aes","gcm","none"],Ke=(n,t)=>({v:2,adata:ve(),ct:P(t),pasteid:n,parentid:n});async function F(n){if(n.status===429)throw new u(H(n));if(!n.ok)throw new Error(`HTTP ${n.status}`);let[t]=await E(n);if(t.status===0)return t;let e=Number(/\d+/.exec(String(t.message??""))?.[0]);throw new u(e>=1&&e<=3600?e:30,!0)}async function Ge(n,t,e,r="never",i){let o=P(await A(e,"share",[])),s=await F(await n(t,{...B({v:2,adata:[ve(),"plaintext",1,0],ct:o,meta:{expire:r}}),signal:i}));if(typeof s.id!="string"||typeof s.deletetoken!="string")throw new Error("the answer had no paste id");return{id:s.id,deleteToken:s.deletetoken}}async function Je(n,t,e,r){return n(t,B({pasteid:e,deletetoken:r}))}async function Ye(n,t,e,r){let i=await z(n,`${t}?${e}`,r);if(i.status===404)return null;if(!i.ok)throw new Error(`HTTP ${i.status}`);let[o,s]=await E(i);if(o.status!==0)return null;let a=o.meta?.time_to_live;return{j:o,size:s,ttl:typeof a=="number"&&a>0?a*1e3:null}}var K=class{constructor(t,e,r,i,o,s=()=>{}){this.a=t;this.l=e;this.f=r;this.signal=i;this.onGen=s;this.head=o||t.paste,this.trail.push(t.paste)}ids=new Set;expires=null;moved=!1;big=!1;head;trail=[];seen=new Map;async scan(t,e){let r;for(let i of Array.isArray(t)?t:[]){if(typeof i?.id!="string"||typeof i.ct!="string")continue;let o=this.seen.get(i.id);if(o===void 0){o=null;let s=null;try{i.ct.length<14e5&&(s=Q(i.ct))}catch{}let a=s&&await C(this.l,"share",s),d=a?.next,l=typeof d=="string"?null:N(this.l,a);if(typeof d=="string"&&Fe.test(d))o=d;else if(l){e.push(l);for(let f of _(l.ops))this.ids.add(f)}this.seen.set(i.id,o)}r??=o??void 0}return r}async read(){let t=[],e=this.head,r=!1,i=!1;for(let o=0;;){let s=await Ye(this.f,this.a.base,e,this.signal);if(!s){if(i)break;if(!r&&e!==this.a.paste){r=!0,e=this.a.paste;continue}throw new b("gone")}i=!0,e!==this.head&&(this.head=e,this.trail.push(e),this.ids.clear(),this.moved=!0,this.onGen(e));let a=s.j.comments,d=await this.scan(a,t);this.expires=s.ttl&&Date.now()+s.ttl;let l=(Array.isArray(a)?a[0]?.ct?.length:0)??0;if(this.big=!d&&s.size>je&&s.size>2*l,!d||++o>=qe)break;e=d}return t}ask(t,e){return[this.a.base,B(Ke(t,e))]}async req(t){return this.ask(this.head,await A(this.l,"share",t))}go(t,e){return this.f(t,{...e,signal:this.signal})}async post(t){for(let e of $(t))await F(await this.go(...await this.req(e)))}async roll(t){let e=async s=>{for(let a=0;;a++)try{return await s()}catch(d){if(!(d instanceof u)||a>5||this.signal?.aborted)throw d;await U(d.seconds*1e3*(1+Math.random()*.2),this.signal)}},r=this.head,i=await e(()=>Ge(this.f,this.a.base,this.l,"never",this.signal));for(let s of $(t))await e(async()=>F(await this.go(...this.ask(i.id,await A(this.l,"share",s)))));await e(async()=>F(await this.go(...this.ask(r,await L(this.l,"share",{next:i.id})))));let o=await this.read();return this.head!==i.id&&await Je(this.f,this.a.base,i.id,i.deleteToken).catch(()=>{}),o}};function Ze(n,t,e,r=Math.random()){let i=t?3e5:n<6e5?25e3+r*1e4:n<18e5?12e4:3e5;return Math.min(3e5,i*2**e)}var G=class{constructor(t,e){this.b=t;this.o=e}id="share";problem=null;offline=!1;newer=0;deliver=()=>{};active=Date.now();errors=0;ok=!1;timer;busy=null;again=!1;limit=0;rolling=!1;ready=null;stopped=!1;off=[];async start(t){this.deliver=t;let e=(i,o,s)=>{i&&(i.addEventListener(o,s),this.off.push(()=>i.removeEventListener(o,s)))},r=globalThis;r.addEventListener&&(e(globalThis,"focus",()=>void this.poll()),e(globalThis,"online",()=>void this.poll()),e(globalThis,"pagehide",()=>this.flush()),e(r.document,"visibilitychange",()=>r.document?.visibilityState==="visible"&&void this.poll())),await this.poll()}stop(){this.stopped=!0,clearTimeout(this.timer);for(let t of this.off.splice(0))t()}async remoteIds(){return this.ok?this.b.ids:null}poll(){if(this.busy)return this.again=!0,this.busy;let t=async()=>{do this.again=!1,await this.read();while(this.again&&!this.stopped)};return this.busy=t().finally(()=>this.busy=null)}bump(){this.active=Date.now()}async read(){clearTimeout(this.timer);try{let t=await this.b.read();this.offline=!1,this.errors=0,this.ok=!0,this.newer+=t.reduce((r,i)=>r+i.newer,0);let e=t.flatMap(r=>r.ops);if(e.length&&(this.active=Date.now(),this.deliver(e)),this.b.moved){this.b.moved=!1;let r=this.o.allowed().filter(i=>!this.b.ids.has(i.body.id));r.length&&await this.b.post(r).catch(()=>{})}this.b.big&&!this.rolling&&this.roll()}catch(t){t instanceof b?this.problem=t.kind:(this.offline=!0,this.errors++)}if(this.o.changed(),!this.stopped&&this.problem!=="gone"){let t=globalThis.document?.visibilityState==="hidden";this.timer=setTimeout(()=>void this.poll(),Ze(Date.now()-this.active,t,this.errors))}}lock(t,e=0){let r=this.o.lock,i=globalThis.navigator?.locks;return r?i?new Promise((o,s)=>{i.request(r,{signal:this.o.signal},async()=>{try{o(await t())}catch(a){s(a)}await U(e,this.o.signal)}).catch(s)}):U(Math.random()*5e3,this.o.signal).then(t):t()}get gap(){return Math.max(this.o.gap,this.limit)}async guarded(t){try{await this.lock(t,this.gap),this.offline=!1}catch(e){throw e instanceof u?(e.limit&&(this.limit=Math.max(this.limit,e.seconds*1e3)),e):e instanceof b?(this.problem=e.kind,this.o.changed(),new u(3600)):(this.offline=!0,this.o.changed(),e)}}async send(t){if(this.problem)throw new u(3600);this.bump(),await this.guarded(async()=>{await this.poll();let e=t.filter(r=>!this.b.ids.has(r.body.id));if(e.length){await this.b.post(e);for(let r of e)this.b.ids.add(r.body.id)}})}async prepare(t){try{this.ready=t.length&&JSON.stringify(t).length<4e4?await this.b.req(t):null}catch{this.ready=null}}flush(){let t=this.ready;this.ready=null,!(!t||this.problem||typeof t[1].body!="string"||t[1].body.length>64e3)&&(this.o.fetch??fetch)(t[0],{...t[1],keepalive:!0}).catch(()=>{})}async roll(){this.rolling=!0;try{await U(Math.random()*3e4,this.o.signal),await this.guarded(async()=>{if(await this.poll(),!this.b.big||!this.b.roll)return;let e=(await this.b.roll(this.o.allowed())).flatMap(r=>r.ops);e.length&&this.deliver(e)})}catch{}finally{this.rolling=!1}}};var Xe="Comments here are shared with everyone who has this page.",We=7*864e5,ke=["M12 16V4M7 9l5-5 5 5M5 20h14"],Ve=["M4 7a3 3 0 0 1 3-3h10a3 3 0 0 1 3 3v10a3 3 0 0 1-3 3H7a3 3 0 0 1-3-3z","M4 9.5h16M7.5 6.8h.01"],Qe="Only in this browser",et={held:"Written before this page was shared. Share it or keep it from the menu.",kept:"Written while Send my comments was off. It stays here.",chosen:"You chose to keep it here.",thread:"Part of a comment that stays in this browser.",unknown:"It stays in this browser and isn't sent to the shared copy."};function Se(n={}){return{id:"share",api:1,version:"0.4.1",needs:["sync","menu","notify","note","commentmark"],network:{when:"page-configured",to:["page"],says:"Sends the comments you choose to share, sealed so only people with this page can read them, to the sharing service the page names. That service sees when and how much is sent, and your network address."},async setup(t){let e=t.document,r=ge(n.share??S("data-pipeup-share"),!0);if(r.kind==="off")return t.off(r.reason);if(!ee(e.id))return t.off("needs a document identity");let i=te(e.id,r.key),o=await oe("share",{memory:t.ephemeral}),s=await o.get(`doc:${e.id}`),a=new q(e.me,s,we);a.hold(e.ops());let d=Promise.resolve(),l=()=>{d=d.then(()=>o.set(`doc:${e.id}`,a.saved())).catch(()=>{})};l();let f={gone:"The shared copy is gone",closed:"This page can't send to the shared copy; ask the author for the current file",full:"The shared copy is full; the author can start it again"},se=new Set,ae=(c,p)=>se.has(c)||(se.add(c),t.notify(p)),J=new Set,de=()=>{let c=new Set;for(let p of e.ops()){if(p.body.kind!=="create"&&p.body.kind!=="reply")continue;let g=h.problem==="gone"?null:a.local(p);g&&(c.add(p.body.id),t.setCommentMark(p.body.id,{text:Qe,tip:et[g]}))}for(let p of J)c.has(p)||t.setCommentMark(p,null);J.clear();for(let p of c)J.add(p)},x=()=>{de();for(let c of I)c.update();t.setStatus({text:pe()}),t.setComposerNote(a.send&&!a.noted&&h.problem!=="gone"?Xe:null),h.newer&&ae("newer",`${h.newer} comments come from a newer version of Pipeup; this page can't show them yet.`),h.problem&&ae(h.problem,f[h.problem]+(h.problem==="gone"?". Your comments stay in this browser.":"."))},le=(c,p)=>fetch(c,p),ce=r.kind==="mailbox"?new j(r,i,le,t.signal):new K(r,i,le,t.signal,a.gen,c=>{a.gen=c,l()}),h=new G(ce,{signal:t.signal,gap:1e4,lock:`pipeup-share:${e.id}`,allowed:()=>e.ops().filter(c=>a.sendable(c)),changed:x}),v=new M({id:"share",document:e,merge:async c=>{let p=await t.merge(c),g=new Set(e.ops().map(y=>y.body.id));for(let y of _(c))g.has(y)&&a.recv.add(y);return l(),p},transport:h,sendable:c=>{let p=a.sendable(c);return a.noted!==s?.noted&&l(),p},signal:t.signal,delay:2e3,gap:()=>h.gap}),Y;v.onState(()=>{x(),clearTimeout(Y),Y=setTimeout(()=>void h.prepare(v.pending()),1e3)});let Ae=new URL(r.kind==="mailbox"?r.mailbox:r.base).host,pe=()=>{let c=v.waiting;return h.problem?f[h.problem]:a.send?h.offline||v.state==="offline"?"Shared \xB7 offline, sends when back":c?`Shared \xB7 ${c} change${c===1?"":"s"} waiting`:"Shared \xB7 up to date":"Shared \xB7 not sending your comments"},xe=()=>{let c=ce.expires;return h.problem==="gone"?"Your comments stay in this browser. The author can start sharing again.":[`Your comments are encrypted and sent to ${Ae} so others with this page see them. The service can't read them. People who already have your comments, by file or live, could pass them on.`,t.ephemeral&&"This browser can't keep comments; the shared copy keeps the ones you send.",!o.lasting&&"This browser won't remember this choice.",c&&c-Date.now()<We&&`The shared copy expires on ${new Date(c).toLocaleDateString("en-GB",{day:"numeric",month:"long"})}.`].filter(Boolean).join(" ")},I=[],Z=(c,p,g,y,Pe,Te)=>I[I.push(t.addMenuItem({id:c,icon:p,label:g,hint:y,select:Pe,checked:Te}))-1],X=e.ops().filter(c=>a.held.has(c.body.id)&&(c.body.kind==="create"||c.body.kind==="reply")).length;if(Z("send",ke,()=>a.send||h.problem?pe():"Send my comments",xe,()=>{a.send=!a.send,l(),v.rescan(),x()},()=>a.send),X){let c=o.lasting?"":" This browser won't remember this choice.",p=g=>()=>{a.decide(g),l();for(let y of I.splice(1))y.remove();v.rescan(),x()};Z("share-earlier",ke,()=>`Share my ${X} earlier comment${X===1?"":"s"}`,()=>`Send the comments you wrote before this page was shared.${c}`,p(!0)),Z("keep-earlier",Ve,()=>"Keep them in this browser",()=>`Never send the comments you wrote before this page was shared.${c}`,p(!1))}return x(),v.start().then(x,c=>globalThis.reportError?.(c)),e.onChange((c,p,g)=>{if(g==="local"&&p.length){for(let y of p)a.sendable(y);h.bump(),de(),l()}}),()=>{clearTimeout(Y),v.stop()}}}}W(Se());})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pipeup/share",
3
- "version": "0.8.2",
3
+ "version": "0.9.1",
4
4
  "description": "Share Pipeup comments through an encrypted service (PrivateBin or your own HTTP mailbox).",
5
5
  "license": "MIT",
6
6
  "author": "Pipeup contributors",
@@ -30,7 +30,7 @@
30
30
  "LICENSE"
31
31
  ],
32
32
  "peerDependencies": {
33
- "pipeup": "0.8.2"
33
+ "pipeup": "0.9.1"
34
34
  },
35
35
  "pipeup": {
36
36
  "network": {