@semics-tech/emdash-esign-pro 1.0.0-rc.1 → 1.0.0-rc.2

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/LICENSE CHANGED
@@ -1,11 +1,8 @@
1
1
  semics Pro plugins for EmDash: commercial licence
2
- Version 1.0 (draft)
2
+ Version 1.0
3
3
 
4
4
  Copyright (c) 2026 SEMICS LTD. All rights reserved.
5
5
 
6
- [Draft written in plain English by the build agents, not by a lawyer. It needs the lawyer's review before
7
- launch (docs/legal/brief.md §13, question 17). BUILD-PLAN D6 and R90.]
8
-
9
6
  1. Who this licence is between
10
7
 
11
8
  This licence is between SEMICS LTD (company number 12871299), registered in England and Wales, registered
@@ -46,8 +43,9 @@ launch (docs/legal/brief.md §13, question 17). BUILD-PLAN D6 and R90.]
46
43
  support.
47
44
 
48
45
  Your right to use each version released during the Update Term is perpetual: it does not end when the
49
- Update Term ends, when you cancel, or when you stop renewing. A version released after your Update Term
50
- ends needs a renewed key; the key you already have does not unlock it.
46
+ Update Term ends, when you cancel, or when you stop renewing. It does end if you take a refund (section
47
+ 7). A version released after your Update Term ends needs a renewed key; the key you already have does not
48
+ unlock it.
51
49
 
52
50
  The key is checked offline on your site. We cannot switch it off remotely, and your site never needs to
53
51
  contact us for the Software to keep working.
@@ -76,14 +74,16 @@ launch (docs/legal/brief.md §13, question 17). BUILD-PLAN D6 and R90.]
76
74
  7. Refunds and ending this licence
77
75
 
78
76
  You may have a full refund within 14 days of a purchase or renewal, for any reason (see
79
- https://plugins.semics.co.uk/refunds). After a refund we issue no new keys, updates or support for that
80
- licence, and you should remove the key from your site.
77
+ https://plugins.semics.co.uk/refunds). A refund ends this licence for the purchase you were refunded: we
78
+ issue no new keys, updates or support for it, and you must stop using the Software it gave you and remove
79
+ the key from your site. If you refund a renewal, you keep the versions released during the years you paid
80
+ for and were not refunded.
81
81
 
82
82
  If you seriously break section 5 and do not put it right within 30 days of our written notice, we may end
83
83
  this licence. You must then stop using the Software and delete your copies.
84
84
 
85
- Sections 4 (except after we end this licence under this section), 5, 6, 8 and 9 continue after this
86
- licence ends.
85
+ Sections 4 (except after a refund or after we end this licence under this section), 5, 6, 8 and 9
86
+ continue after this licence ends.
87
87
 
88
88
  8. Our responsibility
89
89
 
package/dist/index.mjs CHANGED
@@ -7,7 +7,7 @@
7
7
  /** @type {import("emdash").PluginDescriptor} */
8
8
  const descriptor = Object.freeze({
9
9
  "id": "semics-esign",
10
- "version": "1.0.0-rc.1",
10
+ "version": "1.0.0-rc.2",
11
11
  "format": "standard",
12
12
  "entrypoint": "@semics-tech/emdash-esign-pro/sandbox",
13
13
  "capabilities": [
@@ -254,6 +254,7 @@ const descriptor = Object.freeze({
254
254
  "envelopes/resend",
255
255
  "envelopes/void",
256
256
  "outbox/status",
257
+ "integrations/pair",
257
258
  "pro/licence",
258
259
  "pro/envelopes/send",
259
260
  "pro/templates/self-serve",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "semics-esign",
3
- "version": "1.0.0-rc.1",
3
+ "version": "1.0.0-rc.2",
4
4
  "declaredAccess": {
5
5
  "media": {
6
6
  "read": {},
@@ -261,6 +261,7 @@
261
261
  "envelopes/resend",
262
262
  "envelopes/void",
263
263
  "outbox/status",
264
+ "integrations/pair",
264
265
  "pro/licence",
265
266
  "pro/envelopes/send",
266
267
  "pro/templates/self-serve",
package/dist/plugin.mjs CHANGED
@@ -24,34 +24,34 @@ Get your signed copy here (the page issues a fresh download link each time):
24
24
  {{link}}
25
25
  `,html:`<p>Hello {{name}},</p>
26
26
  <p>Thank you. &quot;{{title}}&quot; for {{sender}} is now signed.</p>
27
- <p><a href="{{link}}">Get your signed copy</a> (the page issues a fresh download link each time).</p>`},{name:e.signerName,title:e.title,sender:e.sender,link:e.link})}const er=`outbox-drain`;function I(e){let t=e.storage.outbox;return{put:(e,n)=>t.put(e,n),putMany:e=>t.putMany([...e]),query:({status:e,nextAttemptAtLte:n,limit:r})=>t.query({where:{status:e,...n===void 0?{}:{nextAttemptAt:{lte:n}}},orderBy:{nextAttemptAt:`asc`},limit:r})}}function L(e){try{let{origin:t}=new URL(e.site.url);return t===`null`?``:t}catch{return``}}const tr=(e,t)=>typeof t==`string`&&t.trim()!==``?t.trim():e.site.name,nr=`The site URL is not set, so signing invitations and signed-copy emails are not queued (their links would not work). Set the site URL in EmDash's settings, then use Resend invitation.`;async function rr(e,t){let{signerId:n,envelope:r,token:i,now:a}=t,o=L(e);if(!o)return null;let s=Qn({to:r.signer.email,signerName:r.signer.name,title:r.title,sender:tr(e,t.senderSetting),link:`${o}/sign/${i}`,expiresAt:r.expiresAt});return At(I(e),s,a,()=>`invite-${n}`)}async function ir(e,t){let n=L(e);if(!n)return null;let r={to:t.envelope.signer.email,signerName:t.envelope.signer.name,title:t.envelope.title,sender:tr(e,t.senderSetting),link:`${n}/signed/${t.token}`};return At(I(e),$n(r),t.now,()=>`complete-${t.envelopeId}`)}async function ar(e,t,n=Date.now()){if(e.name!==er)return!1;let r=await Mt({storage:I(t),email:t.email,now:n});return r.gaveUp>0&&t.log.error(`emails given up after repeated failures`,{count:r.gaveUp}),!0}async function or(e){return Nt({storage:I(e),email:e.email,now:Date.now()})}const sr=`0`.repeat(64);function cr(e=T){return D(e(32))}function lr(e,t){return F(e+t)}function ur(e,t){return`${e}:a${String(t).padStart(6,`0`)}`}const dr=e=>Object.keys(e).sort().map(t=>[t,e[t]]);function fr(e){let t=JSON.stringify([1,e.envelopeId,e.seq,e.type,e.at,e.actor,dr(e.data),dr(e.commitments)]);return F(e.prevHash+t)}async function pr(e,t,n,r){let i=Object.entries(n.personal??{}).filter(e=>typeof e[1]==`string`),a={};for(let[e,t]of i)a[e]=await lr(r,t);let o={envelopeId:e,seq:t?t.seq+1:0,type:n.type,at:n.at,actor:n.actor,data:{...n.data},commitments:a,prevHash:t?t.hash:sr};return{...o,personal:i.length>0?Object.fromEntries(i):null,hash:await fr(o)}}function mr(e,t,n){return hr(e,null,t,n)}async function hr(e,t,n,r){let i=[],a=t;for(let t of n){let n=await pr(e,a,t,r);i.push({id:ur(e,n.seq),data:n}),a=n}return i}async function gr(e,t,n,r){let i=r.attempts??2;for(let a=0;a<i;a++){let{items:i}=await e.query({where:{envelopeId:t},orderBy:{seq:`desc`},limit:1}),a=await pr(t,i[0]?.data??null,n,r.salt);if((await e.compareAndSet(ur(t,a.seq),null,a)).applied)return O(a)}return k(`CONFLICT`)}async function _r(e,t){let{items:n}=await e.query({where:{envelopeId:t},orderBy:{seq:`desc`},limit:1});return n[0]?.data??null}async function vr(e,t){let[n,...r]=t;return n?(await e.compareAndSet(n.id,null,n.data)).applied?(r.length>0&&await e.putMany(r),!0):!1:!0}async function yr(e,t){for(let[n,r]of Object.entries(e.personal??{}))if(e.commitments[n]!==await lr(t,r))return!1;return!0}async function br(e,t,n={}){let r=sr;for(let[i,a]of t.entries()){let t=e=>k({seq:i,reason:e});if(a.envelopeId!==e)return t(`ENVELOPE`);if(a.seq!==i)return t(`SEQ`);if(await fr(a)!==a.hash)return t(`HASH`);if(a.prevHash!==r)return t(`PREV_HASH`);if(n.salt!==void 0&&!await yr(a,n.salt))return t(`COMMITMENT`);r=a.hash}return n.head!==void 0&&n.head!==r?k({seq:t.length,reason:`HEAD`}):O({head:r,length:t.length})}function xr(e){return{...e,personal:null}}function Sr(e,t){return F(`esign-final/1\n${e}\n${t}`)}const Cr=[`draft`,`sent`,`in_progress`,`completed`,`declined`,`voided`,`expired`],wr=[`declined`,`voided`,`expired`],Tr=Object.freeze({draft:[`sent`,`voided`],sent:[`in_progress`,`completed`,...wr],in_progress:[`completed`,...wr],completed:[],declined:[],voided:[],expired:[]});function Er(e){return typeof e==`string`&&Cr.includes(e)}function Dr(e,t){return Er(e)&&Er(t)&&Tr[e].includes(t)}function Or(e){return Tr[e].length===0}async function R(e,t,n,r,i={}){if(!Dr(n,r))return k(`ILLEGAL_TRANSITION`);let a=await e.updateIf(t,{where:{status:n},set:{...i,status:r}});return a.applied?O(a.data):k(`CONFLICT`)}const z=(e,t)=>`${e}:v${t}`;function kr(e){if(typeof e!=`object`||!e||Array.isArray(e))return k([{path:``,code:`INVALID_INPUT`}]);let{name:t,body:n,description:r,integrations:i}=e,a=[],o=typeof t==`string`?t.trim():``;return(o.length===0||o.length>200)&&a.push({path:`name`,code:`INVALID_NAME`}),(typeof n!=`string`||n.trim().length===0||n.length>1e5)&&a.push({path:`body`,code:`INVALID_BODY`}),r!==void 0&&(typeof r!=`string`||r.length>1e3)&&a.push({path:`description`,code:`INVALID_DESCRIPTION`}),i!==void 0&&typeof i!=`boolean`&&a.push({path:`integrations`,code:`INVALID_INTEGRATIONS`}),a.length>0?k(a):O({name:o,body:n,...typeof r==`string`&&r!==``?{description:r}:{},...typeof i==`boolean`?{integrations:i}:{}})}function Ar(e,t){return{...e,status:`version`,templateId:t}}function jr(e,t){let n=kr(e);if(!n.ok)return n;let r={name:n.value.name,...n.value.description===void 0?{}:{description:n.value.description},kind:`text`,status:`active`,public:!1,integrations:n.value.integrations??!1,version:1,body:n.value.body,fields:In(n.value.body),createdAt:t.now,updatedAt:t.now};return O({head:r,versions:[{id:z(t.id,1),data:Ar(r,t.id)}]})}function Mr(e,t,n){if(e.status===`archived`)return k([{path:``,code:`TEMPLATE_ARCHIVED`}]);let r=kr(t);if(!r.ok)return r;let{description:i,...a}=e,o={...a,...r.value.description===void 0?{}:{description:r.value.description},name:r.value.name,body:r.value.body,fields:In(r.value.body),integrations:r.value.integrations??e.integrations===!0,version:e.version+1,updatedAt:n.now};return O({head:o,version:{id:z(n.id,o.version),data:Ar(o,n.id)}})}function Nr(e,t){return e.status===`archived`?e:{...e,status:`archived`,updatedAt:t}}function Pr(e){return e?.status===`active`&&e.integrations===!0}function Fr(e){return e.status===`active`?O(e):k(`TEMPLATE_NOT_FOUND`)}const Ir=/[\u0000-\u001F\u007F]/,Lr=/^[^\s@]+@[^\s@]+\.[^\s@]+$/,Rr=/^[A-Za-z0-9_]{1,64}$/,zr=(e,t)=>`${e}:s${t}`,Br=e=>typeof e==`object`&&!!e&&!Array.isArray(e),Vr=e=>typeof e==`string`&&e.length>0&&e.length<=200&&!e.includes(`:`);function Hr(e){let t=typeof e==`string`?e.trim():``;return t.length>0&&t.length<=200&&!Ir.test(t)?t:null}function Ur(e){let t=typeof e==`string`?e.trim().toLowerCase():``;return t.length<=254&&Lr.test(t)?t:null}function Wr(e){if(e===void 0)return{};if(!Br(e))return null;let t=Object.entries(e);if(t.length>32)return null;let n={};for(let[e,r]of t){if(!Rr.test(e)||typeof r!=`string`||[...r].length>500)return null;n[e]=r}return n}function Gr(e){if(e===void 0)return[];if(!Array.isArray(e)||e.length>16)return null;let t=[];for(let n of e){if(!Br(n)||typeof n.key!=`string`||!Rr.test(n.key)||t.some(e=>e.key===n.key))return null;let e=typeof n.label==`string`?n.label.trim():``;if(e===``||[...e].length>100||Ir.test(e)||n.required!==void 0&&typeof n.required!=`boolean`)return null;t.push({key:n.key,label:e,...n.required?{required:!0}:{}})}return t}function Kr(e){if(!Br(e))return k([{path:``,code:`INVALID_INPUT`}]);let{templateId:t,templateVersion:n,title:r,signer:i,fields:a}=e,o=[];Vr(t)||o.push({path:`templateId`,code:`INVALID_TEMPLATE_ID`}),n!==void 0&&!(Number.isSafeInteger(n)&&n>=1)&&o.push({path:`templateVersion`,code:`INVALID_VERSION`});let s=typeof r==`string`?r.trim():void 0;r!==void 0&&!(s&&s.length<=200&&!Ir.test(s))&&o.push({path:`title`,code:`INVALID_TITLE`});let c=Br(i)?i:{},l=Hr(c.name),u=Ur(c.email);l===null&&o.push({path:`signer.name`,code:`INVALID_SIGNER_NAME`}),u===null&&o.push({path:`signer.email`,code:`INVALID_SIGNER_EMAIL`});let d=Wr(a);d===null&&o.push({path:`fields`,code:`INVALID_FIELDS`});let f=Gr(e.signerFields);return f===null&&o.push({path:`signerFields`,code:`INVALID_FIELDS`}),o.length>0?k(o):O({templateId:t,...n===void 0?{}:{templateVersion:n},...s===void 0?{}:{title:s},signer:{name:l,email:u,as:`self`},fieldValues:d,...f&&f.length>0?{signerFields:f}:{}})}function qr(e,t,n){let r=e?Fr(e):k(`TEMPLATE_NOT_FOUND`);return!r.ok||n===void 0?r:t?.status===`version`&&t.version===n?O(t):k(`TEMPLATE_NOT_FOUND`)}function Jr(e){let{signer:t}=e;return{...e.fieldValues,"signer.name":t.name,"signer.email":t.email,...t.participant?{"participant.name":t.participant.name}:{}}}function Yr(e,t){let n=Jr(e);return In(t).filter(e=>!Object.hasOwn(n,e)).map(e=>({path:`fields.${e}`,code:`MISSING_FIELD`}))}function Xr(e,t,n){let{title:r,...i}=e,a={title:r??t.name,templateVersion:t.version,status:`draft`,routing:`parallel`,...i,signerEmail:i.signer.email.toLowerCase(),signerIds:[],docSha256:null,snapshot:null,expiresAt:null,sentAt:null,completedAt:null,finalHash:null,piiSalt:n.piiSalt,createdAt:n.now,updatedAt:n.now},o=Yr(a,t.body);return o.length>0?k(o):O(a)}function Zr(e,t,n){return Xr({templateId:e.templateId,signer:e.signer,fieldValues:e.fieldValues,delivery:`email`,...e.title===void 0?{}:{title:e.title},...e.signerFields?{signerFields:e.signerFields}:{}},t,n)}function Qr(e,t,n){let r={name:e.signer.name.trim(),email:e.signer.email.trim().toLowerCase(),as:e.as??`self`,...e.participant?{participant:{name:e.participant.name.trim()}}:{}};return Xr({templateId:e.tpl,signer:r,fieldValues:{...e.prefill},delivery:e.delivery??`inline`,clientId:e.cid,externalRef:e.ref,returnUrl:e.returnUrl},t,n)}function $r(e){let t=0;for(let n=e.indexOf(`
27
+ <p><a href="{{link}}">Get your signed copy</a> (the page issues a fresh download link each time).</p>`},{name:e.signerName,title:e.title,sender:e.sender,link:e.link})}const er=`outbox-drain`;function I(e){let t=e.storage.outbox;return{put:(e,n)=>t.put(e,n),putMany:e=>t.putMany([...e]),query:({status:e,nextAttemptAtLte:n,limit:r})=>t.query({where:{status:e,...n===void 0?{}:{nextAttemptAt:{lte:n}}},orderBy:{nextAttemptAt:`asc`},limit:r})}}function L(e){try{let{origin:t}=new URL(e.site.url);return t===`null`?``:t}catch{return``}}const tr=(e,t)=>typeof t==`string`&&t.trim()!==``?t.trim():e.site.name,nr=`The site URL is not set, so signing invitations and signed-copy emails are not queued (their links would not work). Set the site URL in EmDash's settings, then use Resend invitation.`;async function rr(e,t){let{signerId:n,envelope:r,token:i,now:a}=t,o=L(e);if(!o)return null;let s=Qn({to:r.signer.email,signerName:r.signer.name,title:r.title,sender:tr(e,t.senderSetting),link:`${o}/sign/${i}`,expiresAt:r.expiresAt});return At(I(e),s,a,()=>`invite-${n}`)}async function ir(e,t){let n=L(e);if(!n)return null;let r={to:t.envelope.signer.email,signerName:t.envelope.signer.name,title:t.envelope.title,sender:tr(e,t.senderSetting),link:`${n}/signed/${t.token}`};return At(I(e),$n(r),t.now,()=>`complete-${t.envelopeId}`)}async function ar(e,t,n=Date.now()){if(e.name!==er)return!1;let r=await Mt({storage:I(t),email:t.email,now:n});return r.gaveUp>0&&t.log.error(`emails given up after repeated failures`,{count:r.gaveUp}),!0}async function or(e){return Nt({storage:I(e),email:e.email,now:Date.now()})}const sr=`0`.repeat(64);function cr(e=T){return D(e(32))}function lr(e,t){return F(e+t)}function ur(e,t){return`${e}:a${String(t).padStart(6,`0`)}`}const dr=e=>Object.keys(e).sort().map(t=>[t,e[t]]);function fr(e){let t=JSON.stringify([1,e.envelopeId,e.seq,e.type,e.at,e.actor,dr(e.data),dr(e.commitments)]);return F(e.prevHash+t)}async function pr(e,t,n,r){let i=Object.entries(n.personal??{}).filter(e=>typeof e[1]==`string`),a={};for(let[e,t]of i)a[e]=await lr(r,t);let o={envelopeId:e,seq:t?t.seq+1:0,type:n.type,at:n.at,actor:n.actor,data:{...n.data},commitments:a,prevHash:t?t.hash:sr};return{...o,personal:i.length>0?Object.fromEntries(i):null,hash:await fr(o)}}function mr(e,t,n){return hr(e,null,t,n)}async function hr(e,t,n,r){let i=[],a=t;for(let t of n){let n=await pr(e,a,t,r);i.push({id:ur(e,n.seq),data:n}),a=n}return i}async function gr(e,t,n,r){let i=r.attempts??2;for(let a=0;a<i;a++){let{items:i}=await e.query({where:{envelopeId:t},orderBy:{seq:`desc`},limit:1}),a=await pr(t,i[0]?.data??null,n,r.salt);if((await e.compareAndSet(ur(t,a.seq),null,a)).applied)return O(a)}return k(`CONFLICT`)}async function _r(e,t){let{items:n}=await e.query({where:{envelopeId:t},orderBy:{seq:`desc`},limit:1});return n[0]?.data??null}async function vr(e,t){let[n,...r]=t;return n?(await e.compareAndSet(n.id,null,n.data)).applied?(r.length>0&&await e.putMany(r),!0):!1:!0}async function yr(e,t){for(let[n,r]of Object.entries(e.personal??{}))if(e.commitments[n]!==await lr(t,r))return!1;return!0}async function br(e,t,n={}){let r=sr;for(let[i,a]of t.entries()){let t=e=>k({seq:i,reason:e});if(a.envelopeId!==e)return t(`ENVELOPE`);if(a.seq!==i)return t(`SEQ`);if(await fr(a)!==a.hash)return t(`HASH`);if(a.prevHash!==r)return t(`PREV_HASH`);if(n.salt!==void 0&&!await yr(a,n.salt))return t(`COMMITMENT`);r=a.hash}return n.head!==void 0&&n.head!==r?k({seq:t.length,reason:`HEAD`}):O({head:r,length:t.length})}function xr(e){return{...e,personal:null}}function Sr(e,t){return F(`esign-final/1\n${e}\n${t}`)}const Cr=[`draft`,`sent`,`in_progress`,`completed`,`declined`,`voided`,`expired`],wr=[`declined`,`voided`,`expired`],Tr=Object.freeze({draft:[`sent`,`voided`],sent:[`in_progress`,`completed`,...wr],in_progress:[`completed`,...wr],completed:[],declined:[],voided:[],expired:[]});function Er(e){return typeof e==`string`&&Cr.includes(e)}function Dr(e,t){return Er(e)&&Er(t)&&Tr[e].includes(t)}function Or(e){return Tr[e].length===0}async function kr(e,t,n,r,i={}){if(!Dr(n,r))return k(`ILLEGAL_TRANSITION`);let a=await e.updateIf(t,{where:{status:n},set:{...i,status:r}});return a.applied?O(a.data):k(`CONFLICT`)}const R=(e,t)=>`${e}:v${t}`;function Ar(e){if(typeof e!=`object`||!e||Array.isArray(e))return k([{path:``,code:`INVALID_INPUT`}]);let{name:t,body:n,description:r,integrations:i}=e,a=[],o=typeof t==`string`?t.trim():``;return(o.length===0||o.length>200)&&a.push({path:`name`,code:`INVALID_NAME`}),(typeof n!=`string`||n.trim().length===0||n.length>1e5)&&a.push({path:`body`,code:`INVALID_BODY`}),r!==void 0&&(typeof r!=`string`||r.length>1e3)&&a.push({path:`description`,code:`INVALID_DESCRIPTION`}),i!==void 0&&typeof i!=`boolean`&&a.push({path:`integrations`,code:`INVALID_INTEGRATIONS`}),a.length>0?k(a):O({name:o,body:n,...typeof r==`string`&&r!==``?{description:r}:{},...typeof i==`boolean`?{integrations:i}:{}})}function jr(e,t){return{...e,status:`version`,templateId:t}}function Mr(e,t){let n=Ar(e);if(!n.ok)return n;let r={name:n.value.name,...n.value.description===void 0?{}:{description:n.value.description},kind:`text`,status:`active`,public:!1,integrations:n.value.integrations??!1,version:1,body:n.value.body,fields:In(n.value.body),createdAt:t.now,updatedAt:t.now};return O({head:r,versions:[{id:R(t.id,1),data:jr(r,t.id)}]})}function Nr(e,t,n){if(e.status===`archived`)return k([{path:``,code:`TEMPLATE_ARCHIVED`}]);let r=Ar(t);if(!r.ok)return r;let{description:i,...a}=e,o={...a,...r.value.description===void 0?{}:{description:r.value.description},name:r.value.name,body:r.value.body,fields:In(r.value.body),integrations:r.value.integrations??e.integrations===!0,version:e.version+1,updatedAt:n.now};return O({head:o,version:{id:R(n.id,o.version),data:jr(o,n.id)}})}function Pr(e,t){return e.status===`archived`?e:{...e,status:`archived`,updatedAt:t}}function Fr(e){return e?.status===`active`&&e.integrations===!0}function Ir(e){return e.status===`active`?O(e):k(`TEMPLATE_NOT_FOUND`)}const Lr=/[\u0000-\u001F\u007F]/,Rr=/^[^\s@]+@[^\s@]+\.[^\s@]+$/,zr=/^[A-Za-z0-9_]{1,64}$/,Br=(e,t)=>`${e}:s${t}`,Vr=e=>typeof e==`object`&&!!e&&!Array.isArray(e),Hr=e=>typeof e==`string`&&e.length>0&&e.length<=200&&!e.includes(`:`);function Ur(e){let t=typeof e==`string`?e.trim():``;return t.length>0&&t.length<=200&&!Lr.test(t)?t:null}function Wr(e){let t=typeof e==`string`?e.trim().toLowerCase():``;return t.length<=254&&Rr.test(t)?t:null}function Gr(e){if(e===void 0)return{};if(!Vr(e))return null;let t=Object.entries(e);if(t.length>32)return null;let n={};for(let[e,r]of t){if(!zr.test(e)||typeof r!=`string`||[...r].length>500)return null;n[e]=r}return n}function Kr(e){if(e===void 0)return[];if(!Array.isArray(e)||e.length>16)return null;let t=[];for(let n of e){if(!Vr(n)||typeof n.key!=`string`||!zr.test(n.key)||t.some(e=>e.key===n.key))return null;let e=typeof n.label==`string`?n.label.trim():``;if(e===``||[...e].length>100||Lr.test(e)||n.required!==void 0&&typeof n.required!=`boolean`)return null;t.push({key:n.key,label:e,...n.required?{required:!0}:{}})}return t}function qr(e){if(!Vr(e))return k([{path:``,code:`INVALID_INPUT`}]);let{templateId:t,templateVersion:n,title:r,signer:i,fields:a}=e,o=[];Hr(t)||o.push({path:`templateId`,code:`INVALID_TEMPLATE_ID`}),n!==void 0&&!(Number.isSafeInteger(n)&&n>=1)&&o.push({path:`templateVersion`,code:`INVALID_VERSION`});let s=typeof r==`string`?r.trim():void 0;r!==void 0&&!(s&&s.length<=200&&!Lr.test(s))&&o.push({path:`title`,code:`INVALID_TITLE`});let c=Vr(i)?i:{},l=Ur(c.name),u=Wr(c.email);l===null&&o.push({path:`signer.name`,code:`INVALID_SIGNER_NAME`}),u===null&&o.push({path:`signer.email`,code:`INVALID_SIGNER_EMAIL`});let d=Gr(a);d===null&&o.push({path:`fields`,code:`INVALID_FIELDS`});let f=Kr(e.signerFields);return f===null&&o.push({path:`signerFields`,code:`INVALID_FIELDS`}),o.length>0?k(o):O({templateId:t,...n===void 0?{}:{templateVersion:n},...s===void 0?{}:{title:s},signer:{name:l,email:u,as:`self`},fieldValues:d,...f&&f.length>0?{signerFields:f}:{}})}function Jr(e,t,n){let r=e?Ir(e):k(`TEMPLATE_NOT_FOUND`);return!r.ok||n===void 0?r:t?.status===`version`&&t.version===n?O(t):k(`TEMPLATE_NOT_FOUND`)}function Yr(e){let{signer:t}=e;return{...e.fieldValues,"signer.name":t.name,"signer.email":t.email,...t.participant?{"participant.name":t.participant.name}:{}}}function Xr(e,t){let n=Yr(e);return In(t).filter(e=>!Object.hasOwn(n,e)).map(e=>({path:`fields.${e}`,code:`MISSING_FIELD`}))}function Zr(e,t,n){let{title:r,...i}=e,a={title:r??t.name,templateVersion:t.version,status:`draft`,routing:`parallel`,...i,signerEmail:i.signer.email.toLowerCase(),signerIds:[],docSha256:null,snapshot:null,expiresAt:null,sentAt:null,completedAt:null,finalHash:null,piiSalt:n.piiSalt,createdAt:n.now,updatedAt:n.now},o=Xr(a,t.body);return o.length>0?k(o):O(a)}function Qr(e,t,n){return Zr({templateId:e.templateId,signer:e.signer,fieldValues:e.fieldValues,delivery:`email`,...e.title===void 0?{}:{title:e.title},...e.signerFields?{signerFields:e.signerFields}:{}},t,n)}function $r(e,t,n){let r={name:e.signer.name.trim(),email:e.signer.email.trim().toLowerCase(),as:e.as??`self`,...e.participant?{participant:{name:e.participant.name.trim()}}:{}};return Zr({templateId:e.tpl,signer:r,fieldValues:{...e.prefill},delivery:e.delivery??`inline`,clientId:e.cid,externalRef:e.ref,returnUrl:e.returnUrl},t,n)}function ei(e){let t=0;for(let n=e.indexOf(`
28
28
  `);n!==-1;n=e.indexOf(`
29
- `,n+1))t++;return t}async function ei(e,t){let n;try{n=Ln(t,Jr(e))}catch(e){if(e instanceof Mn)return k([{path:`fields.${e.field}`,code:`MISSING_FIELD`}]);throw e}let r=Rn(n);return r.length>131072||$r(r)>1500?k([{path:`body`,code:`DOCUMENT_TOO_LARGE`}]):O({text:r,docSha256:await F(r)})}const ti=e=>e>=55296&&e<=56319;function ni(e,t,n){let r=[];for(let e=0;e<t.length;){let n=Math.min(e+65536,t.length);n<t.length&&ti(t.charCodeAt(n-1))&&n--,r.push(t.slice(e,n)),e=n}let i=`${e}:${n.slice(0,16)}`;return r.map((t,a)=>({id:`${i}:${a}`,data:{envelopeId:e,contentType:`text/markdown`,index:a,count:r.length,data:t,sha256:n}}))}function ri(e){let t=e[0];if(!t||e.length!==t.count)return null;let n=[...e].sort((e,t)=>e.index-t.index);return n.every((e,n)=>e.index===n&&e.count===t.count&&e.sha256===t.sha256)?n.map(e=>e.data).join(``):null}async function ii(e,t,n,r){if(!Dr(t.status,`sent`))return k(`ILLEGAL_TRANSITION`);if(n.version!==t.templateVersion)return k(`TEMPLATE_MISMATCH`);let i=await ei(t,n.body);if(!i.ok)return i;let{text:a,docSha256:o}=i.value,s=ni(e,a,o),c=zr(e,1),{signer:l}=t;return O({envelope:{...t,status:`sent`,docSha256:o,snapshot:{ids:s.map(e=>e.id),length:a.length},signerIds:[c],sentAt:r.now,expiresAt:N(Date.parse(r.now)+r.expiryDays*864e5),updatedAt:r.now},chunks:s,signer:{id:c,data:{envelopeId:e,order:1,role:`signer`,name:l.name,email:l.email,as:l.as,...l.participant?{participant:l.participant}:{},status:`pending`,tokenHash:r.tokenHash,createdAt:r.now}}})}const ai=[`declined`,`voided`,`expired`];function oi(e){return e.find(e=>!ai.includes(e.data.status))}async function si(e,t,n){return`env_${(await F(`${e}\n${t}`)).slice(0,32)}_${n}`}function ci(e,t,n){let{signer:r,clientId:i,externalRef:a}=e;return{type:`envelope.created`,at:e.createdAt,actor:t,data:{source:t===`admin`?`admin`:`intent`,templateId:e.templateId,templateVersion:e.templateVersion,title:e.title,delivery:e.delivery,as:r.as,...i===void 0?{}:{clientId:i},...a===void 0?{}:{externalRef:a},...n?{userId:n}:{}},personal:{name:r.name,email:r.email,...r.participant?{participant:r.participant.name}:{}}}}function li(e,t,n){return{type:`envelope.sent`,at:e.updatedAt,actor:t,data:{docSha256:e.docSha256,expiresAt:e.expiresAt,signerIds:e.signerIds.join(`,`),...n?{userId:n}:{}},personal:{email:e.signer.email}}}function ui(e={}){let t=[];return new Headers(e.headers).forEach((e,n)=>t.push([n,e])),{__emdashPluginResponse:!0,status:e.status??200,headers:t,body:e.body??null}}const di={amp:`&`,lt:`<`,gt:`>`,quot:`"`,"#39":`'`},fi=/^&(amp|lt|gt|quot|#39);/,pi=/[!-/:-@[-`{-~]/,mi=/[\p{L}\p{N}]/u,hi=/[\s"'<>`\\\u0000-\u001F\u007F]/,gi=/^(https?:\/\/|mailto:)/i,_i=new Set([`\\`,`&`,`
30
- `,"`",`*`,`_`,`[`,`!`,`<`]),vi=/[\\&\n`*_[!<]/g;function yi(e){if(!(e.length===0||hi.test(e)||!gi.test(e)))try{return new URL(e).href}catch{return}}function bi(e){return e.replace(/\\([!-/:-@[-`{-~])|&(amp|lt|gt|quot|#39);/g,(e,t,n)=>t===void 0?di[n]:t)}function xi(e){let t=new Map,n={"]":[],")":[]},r={"[":`]`,"(":`)`},i=/[\\[\]()]/g;for(let a=i.exec(e);a;a=i.exec(e)){let e=a.index,o=a[0];if(o===`\\`)i.lastIndex=e+2;else if(o in r)n[r[o]]?.push(e);else{let r=n[o]?.pop();r!==void 0&&t.set(r,e)}}return t}var Si=class{partner;memo=new Map;constructor(e){this.src=e,this.partner=xi(e)}parse(e,t,n){let{src:r}=this,i=[],a=``,o=()=>{a&&i.push({type:`text`,text:a}),a=``},s=e;for(;s<t;){let e=r[s];if(!_i.has(e)){vi.lastIndex=s;let e=vi.exec(r),n=e&&e.index<t?e.index:t;a+=r.slice(s,n),s=n;continue}if(e===`\\`&&s+1<t&&pi.test(r[s+1])){a+=r[s+1],s+=2;continue}let c=e===`&`?fi.exec(r.slice(s,Math.min(t,s+6))):null;if(c){a+=di[c[1]],s+=c[0].length;continue}if(e===`
31
- `){o(),i.push({type:`break`}),s++;continue}let l=n<6?this.markup(s,t,n):void 0;l?.inline?(o(),i.push(l.inline)):a+=l?l.text:e,s=l?l.end:s+1}return o(),i}markup(e,t,n){let r=this.src[e];if(r==="`")return this.codeSpan(e,t);if(r===`*`||r===`_`)return this.emphasis(e,t,n);if(r===`[`)return this.link(e,t,n,!1);if(r===`!`&&this.src[e+1]===`[`)return this.link(e+1,t,n,!0);if(r===`<`)return this.autolink(e,t)}next(e,t,n,r){let i=this.memo.get(e);if(i&&t>=i.from&&(i.at===-1||t<=i.at))return i.at;let a=n(t);for(;a!==-1&&!r(a);)a=n(a+1);return this.memo.set(e,{from:t,at:a}),a}escaped(e){let t=0;for(let n=e-1;n>=0&&this.src[n]===`\\`;n--)t++;return t%2==1}codeSpan(e,t){let{src:n}=this,r=1;for(;n[e+r]==="`";)r++;let i="`".repeat(r),a=this.next(`code${r}`,e+r,e=>n.indexOf(i,e),e=>n[e-1]!=="`"&&n[e+r]!=="`");return a===-1||a+r>t?{text:i,end:e+r}:{inline:{type:`code`,text:bi(n.slice(e+r,a))},end:a+r}}emphasis(e,t,n){let{src:r}=this,i=r[e],a=r[e+1]===i?i+i:i,o=e+a.length,s=e=>e>=0&&e<r.length&&mi.test(r[e]),c=e=>i===`_`&&s(e),l={text:a,end:o};if(c(e-1)||o>=t||/\s/.test(r[o]))return l;let u=this.next(a,o+1,e=>r.indexOf(a,e),e=>!this.escaped(e)&&!/\s/.test(r[e-1])&&!c(e+a.length));if(u===-1||u+a.length>t)return l;let d=this.parse(o,u,n+1);return{inline:{type:a.length===2?`strong`:`em`,children:d},end:u+a.length}}link(e,t,n,r){let{src:i}=this,a={text:r?`![`:`[`,end:e+1},o=this.partner.get(e);if(o===void 0||o>=t||i[o+1]!==`(`)return a;let s=this.partner.get(o+1);if(s===void 0||s>=t)return a;let c=s+1;if(r)return{text:bi(i.slice(e+1,o)),end:c};let l=yi(bi(i.slice(o+2,s)));return l?{inline:{type:`link`,href:l,children:this.parse(e+1,o,n+1)},end:c}:{text:bi(i.slice(e,c)),end:c}}autolink(e,t){let n=/^<([A-Za-z][A-Za-z0-9+.-]*:[^\s<>]*)>/.exec(this.src.slice(e,Math.min(t,e+2048))),r=n?yi(n[1]):void 0;if(!(!n||!r))return{inline:{type:`link`,href:r,children:[{type:`text`,text:n[1]}]},end:e+n[0].length}}};function Ci(e){return new Si(e).parse(0,e.length,0)}const wi=/^ {0,3}(`{3,}|~{3,})/,Ti=/^ {0,3}(#{1,6})(?:[ \t]+(.*?))?(?:[ \t]+#+)?[ \t]*$/,Ei=/^ {0,3}([-*_])(?:[ \t]*\1){2,}[ \t]*$/,Di=/^ {0,3}> ?(.*)$/,Oi=/^ {0,3}[-*+][ \t]+(.*)$/,ki=/^ {0,3}(\d{1,9})[.)][ \t]+(.*)$/,Ai=e=>e.trim()===``,ji=e=>wi.test(e)||Ti.test(e)||Ei.test(e)||Di.test(e)||Oi.test(e)||ki.test(e);function Mi(e,t){let n=[],r=0;for(;r<e.length;){let i=e[r];if(Ai(i)){r++;continue}let a=wi.exec(i);if(a){let t=a[1],i=RegExp(`^ {0,3}${t[0]}{${t.length},}[ \\t]*$`),o=[];for(r++;r<e.length&&!i.test(e[r]);)o.push(e[r]),r++;r++,n.push({type:`code`,text:bi(o.join(`
32
- `))});continue}if(Ei.test(i)){n.push({type:`rule`}),r++;continue}let o=Ti.exec(i);if(o){let e=Math.min(6,o[1].length+1);n.push({type:`heading`,level:e,children:Ci(o[2]??``)}),r++;continue}if(Di.test(i)&&t<4){let i=[];for(;r<e.length&&Di.test(e[r]);)i.push(Di.exec(e[r])[1]),r++;n.push({type:`quote`,children:Mi(i,t+1)});continue}let s=Oi.test(i),c=ki.exec(i);if(s||c){let t=s?Oi:ki,i=[];for(;r<e.length;){let n=e[r],a=t.exec(n);if(a)i.push([s?a[1]:a[2]]);else if(!Ai(n)&&/^ {2,}\S/.test(n)&&!ji(n.trimStart()))i.at(-1).push(n.trim());else break;r++}n.push({type:`list`,ordered:!s,...c&&c[1]!==`1`?{start:Number(c[1])}:{},items:i.map(e=>Ci(e.join(`
33
- `)))});continue}let l=[i.trim()];for(r++;r<e.length&&!Ai(e[r])&&!ji(e[r]);)l.push(e[r].trim()),r++;n.push({type:`paragraph`,children:Ci(l.join(`
34
- `))})}return n}function Ni(e){return Mi(e.replace(/\r\n?/g,`
29
+ `,n+1))t++;return t}async function ti(e,t){let n;try{n=Ln(t,Yr(e))}catch(e){if(e instanceof Mn)return k([{path:`fields.${e.field}`,code:`MISSING_FIELD`}]);throw e}let r=Rn(n);return r.length>131072||ei(r)>1500?k([{path:`body`,code:`DOCUMENT_TOO_LARGE`}]):O({text:r,docSha256:await F(r)})}const ni=e=>e>=55296&&e<=56319;function ri(e,t,n){let r=[];for(let e=0;e<t.length;){let n=Math.min(e+65536,t.length);n<t.length&&ni(t.charCodeAt(n-1))&&n--,r.push(t.slice(e,n)),e=n}let i=`${e}:${n.slice(0,16)}`;return r.map((t,a)=>({id:`${i}:${a}`,data:{envelopeId:e,contentType:`text/markdown`,index:a,count:r.length,data:t,sha256:n}}))}function ii(e){let t=e[0];if(!t||e.length!==t.count)return null;let n=[...e].sort((e,t)=>e.index-t.index);return n.every((e,n)=>e.index===n&&e.count===t.count&&e.sha256===t.sha256)?n.map(e=>e.data).join(``):null}async function ai(e,t,n,r){if(!Dr(t.status,`sent`))return k(`ILLEGAL_TRANSITION`);if(n.version!==t.templateVersion)return k(`TEMPLATE_MISMATCH`);let i=await ti(t,n.body);if(!i.ok)return i;let{text:a,docSha256:o}=i.value,s=ri(e,a,o),c=Br(e,1),{signer:l}=t;return O({envelope:{...t,status:`sent`,docSha256:o,snapshot:{ids:s.map(e=>e.id),length:a.length},signerIds:[c],sentAt:r.now,expiresAt:N(Date.parse(r.now)+r.expiryDays*864e5),updatedAt:r.now},chunks:s,signer:{id:c,data:{envelopeId:e,order:1,role:`signer`,name:l.name,email:l.email,as:l.as,...l.participant?{participant:l.participant}:{},status:`pending`,tokenHash:r.tokenHash,createdAt:r.now}}})}const oi=[`declined`,`voided`,`expired`];function si(e){return e.find(e=>!oi.includes(e.data.status))}async function ci(e,t,n){return`env_${(await F(`${e}\n${t}`)).slice(0,32)}_${n}`}function li(e,t,n){let{signer:r,clientId:i,externalRef:a}=e;return{type:`envelope.created`,at:e.createdAt,actor:t,data:{source:t===`admin`?`admin`:`intent`,templateId:e.templateId,templateVersion:e.templateVersion,title:e.title,delivery:e.delivery,as:r.as,...i===void 0?{}:{clientId:i},...a===void 0?{}:{externalRef:a},...n?{userId:n}:{}},personal:{name:r.name,email:r.email,...r.participant?{participant:r.participant.name}:{}}}}function ui(e,t,n){return{type:`envelope.sent`,at:e.updatedAt,actor:t,data:{docSha256:e.docSha256,expiresAt:e.expiresAt,signerIds:e.signerIds.join(`,`),...n?{userId:n}:{}},personal:{email:e.signer.email}}}function di(e={}){let t=[];return new Headers(e.headers).forEach((e,n)=>t.push([n,e])),{__emdashPluginResponse:!0,status:e.status??200,headers:t,body:e.body??null}}const fi={amp:`&`,lt:`<`,gt:`>`,quot:`"`,"#39":`'`},pi=/^&(amp|lt|gt|quot|#39);/,mi=/[!-/:-@[-`{-~]/,hi=/[\p{L}\p{N}]/u,gi=/[\s"'<>`\\\u0000-\u001F\u007F]/,_i=/^(https?:\/\/|mailto:)/i,vi=new Set([`\\`,`&`,`
30
+ `,"`",`*`,`_`,`[`,`!`,`<`]),yi=/[\\&\n`*_[!<]/g;function bi(e){if(!(e.length===0||gi.test(e)||!_i.test(e)))try{return new URL(e).href}catch{return}}function xi(e){return e.replace(/\\([!-/:-@[-`{-~])|&(amp|lt|gt|quot|#39);/g,(e,t,n)=>t===void 0?fi[n]:t)}function Si(e){let t=new Map,n={"]":[],")":[]},r={"[":`]`,"(":`)`},i=/[\\[\]()]/g;for(let a=i.exec(e);a;a=i.exec(e)){let e=a.index,o=a[0];if(o===`\\`)i.lastIndex=e+2;else if(o in r)n[r[o]]?.push(e);else{let r=n[o]?.pop();r!==void 0&&t.set(r,e)}}return t}var Ci=class{partner;memo=new Map;constructor(e){this.src=e,this.partner=Si(e)}parse(e,t,n){let{src:r}=this,i=[],a=``,o=()=>{a&&i.push({type:`text`,text:a}),a=``},s=e;for(;s<t;){let e=r[s];if(!vi.has(e)){yi.lastIndex=s;let e=yi.exec(r),n=e&&e.index<t?e.index:t;a+=r.slice(s,n),s=n;continue}if(e===`\\`&&s+1<t&&mi.test(r[s+1])){a+=r[s+1],s+=2;continue}let c=e===`&`?pi.exec(r.slice(s,Math.min(t,s+6))):null;if(c){a+=fi[c[1]],s+=c[0].length;continue}if(e===`
31
+ `){o(),i.push({type:`break`}),s++;continue}let l=n<6?this.markup(s,t,n):void 0;l?.inline?(o(),i.push(l.inline)):a+=l?l.text:e,s=l?l.end:s+1}return o(),i}markup(e,t,n){let r=this.src[e];if(r==="`")return this.codeSpan(e,t);if(r===`*`||r===`_`)return this.emphasis(e,t,n);if(r===`[`)return this.link(e,t,n,!1);if(r===`!`&&this.src[e+1]===`[`)return this.link(e+1,t,n,!0);if(r===`<`)return this.autolink(e,t)}next(e,t,n,r){let i=this.memo.get(e);if(i&&t>=i.from&&(i.at===-1||t<=i.at))return i.at;let a=n(t);for(;a!==-1&&!r(a);)a=n(a+1);return this.memo.set(e,{from:t,at:a}),a}escaped(e){let t=0;for(let n=e-1;n>=0&&this.src[n]===`\\`;n--)t++;return t%2==1}codeSpan(e,t){let{src:n}=this,r=1;for(;n[e+r]==="`";)r++;let i="`".repeat(r),a=this.next(`code${r}`,e+r,e=>n.indexOf(i,e),e=>n[e-1]!=="`"&&n[e+r]!=="`");return a===-1||a+r>t?{text:i,end:e+r}:{inline:{type:`code`,text:xi(n.slice(e+r,a))},end:a+r}}emphasis(e,t,n){let{src:r}=this,i=r[e],a=r[e+1]===i?i+i:i,o=e+a.length,s=e=>e>=0&&e<r.length&&hi.test(r[e]),c=e=>i===`_`&&s(e),l={text:a,end:o};if(c(e-1)||o>=t||/\s/.test(r[o]))return l;let u=this.next(a,o+1,e=>r.indexOf(a,e),e=>!this.escaped(e)&&!/\s/.test(r[e-1])&&!c(e+a.length));if(u===-1||u+a.length>t)return l;let d=this.parse(o,u,n+1);return{inline:{type:a.length===2?`strong`:`em`,children:d},end:u+a.length}}link(e,t,n,r){let{src:i}=this,a={text:r?`![`:`[`,end:e+1},o=this.partner.get(e);if(o===void 0||o>=t||i[o+1]!==`(`)return a;let s=this.partner.get(o+1);if(s===void 0||s>=t)return a;let c=s+1;if(r)return{text:xi(i.slice(e+1,o)),end:c};let l=bi(xi(i.slice(o+2,s)));return l?{inline:{type:`link`,href:l,children:this.parse(e+1,o,n+1)},end:c}:{text:xi(i.slice(e,c)),end:c}}autolink(e,t){let n=/^<([A-Za-z][A-Za-z0-9+.-]*:[^\s<>]*)>/.exec(this.src.slice(e,Math.min(t,e+2048))),r=n?bi(n[1]):void 0;if(!(!n||!r))return{inline:{type:`link`,href:r,children:[{type:`text`,text:n[1]}]},end:e+n[0].length}}};function wi(e){return new Ci(e).parse(0,e.length,0)}const Ti=/^ {0,3}(`{3,}|~{3,})/,Ei=/^ {0,3}(#{1,6})(?:[ \t]+(.*?))?(?:[ \t]+#+)?[ \t]*$/,Di=/^ {0,3}([-*_])(?:[ \t]*\1){2,}[ \t]*$/,Oi=/^ {0,3}> ?(.*)$/,ki=/^ {0,3}[-*+][ \t]+(.*)$/,Ai=/^ {0,3}(\d{1,9})[.)][ \t]+(.*)$/,ji=e=>e.trim()===``,Mi=e=>Ti.test(e)||Ei.test(e)||Di.test(e)||Oi.test(e)||ki.test(e)||Ai.test(e);function Ni(e,t){let n=[],r=0;for(;r<e.length;){let i=e[r];if(ji(i)){r++;continue}let a=Ti.exec(i);if(a){let t=a[1],i=RegExp(`^ {0,3}${t[0]}{${t.length},}[ \\t]*$`),o=[];for(r++;r<e.length&&!i.test(e[r]);)o.push(e[r]),r++;r++,n.push({type:`code`,text:xi(o.join(`
32
+ `))});continue}if(Di.test(i)){n.push({type:`rule`}),r++;continue}let o=Ei.exec(i);if(o){let e=Math.min(6,o[1].length+1);n.push({type:`heading`,level:e,children:wi(o[2]??``)}),r++;continue}if(Oi.test(i)&&t<4){let i=[];for(;r<e.length&&Oi.test(e[r]);)i.push(Oi.exec(e[r])[1]),r++;n.push({type:`quote`,children:Ni(i,t+1)});continue}let s=ki.test(i),c=Ai.exec(i);if(s||c){let t=s?ki:Ai,i=[];for(;r<e.length;){let n=e[r],a=t.exec(n);if(a)i.push([s?a[1]:a[2]]);else if(!ji(n)&&/^ {2,}\S/.test(n)&&!Mi(n.trimStart()))i.at(-1).push(n.trim());else break;r++}n.push({type:`list`,ordered:!s,...c&&c[1]!==`1`?{start:Number(c[1])}:{},items:i.map(e=>wi(e.join(`
33
+ `)))});continue}let l=[i.trim()];for(r++;r<e.length&&!ji(e[r])&&!Mi(e[r]);)l.push(e[r].trim()),r++;n.push({type:`paragraph`,children:wi(l.join(`
34
+ `))})}return n}function Pi(e){return Ni(e.replace(/\r\n?/g,`
35
35
  `).split(`
36
- `),0)}const Pi=262144/4*3,Fi=`signed-pdf`,Ii=`This certificate records how the document above was signed. It was signed with a simple electronic signature: the signer consented to sign electronically, confirmed their intent to sign, and signed the exact text identified by the document SHA-256 below. Every step is recorded in a hash-chained audit trail; the final hash binds the document to the end of that trail. Anyone holding this PDF can check these values on the verify page.`,Li={self:`Self`,guardian:`Parent or guardian`,buyer:`Buyer`},Ri=e=>e?`${e.slice(0,10)} ${e.slice(11,19)} UTC`:``;function zi(e){return e.map(e=>{switch(e.type){case`text`:case`code`:return e.text;case`break`:return`
37
- `;case`link`:{let t=zi(e.children);return t===e.href?t:`${t} (${e.href})`}default:return zi(e.children)}}).join(``)}function Bi(e){let t=[],n=(e,r)=>{for(let i of e)switch(i.type){case`heading`:t.push({type:`heading`,text:zi(i.children),level:Math.min(i.level,3)});break;case`paragraph`:t.push({type:`paragraph`,text:zi(i.children),...r?{font:`italic`}:{}});break;case`list`:i.items.forEach((e,n)=>{let a=i.ordered?`${(i.start??1)+n}.`:`•`;t.push({type:`paragraph`,text:`${a} ${zi(e)}`,...r?{font:`italic`}:{}})});break;case`quote`:n(i.children,!0);break;case`code`:t.push({type:`paragraph`,text:i.text,size:9});break;case`rule`:t.push({type:`rule`});break}};return n(Ni(e),!1),t}function Vi(e){let t=e.signature,n=[e.name,`Signed ${Ri(e.signedAt)}`];return t?.kind===`drawn`&&t.strokes?{type:`signature`,label:`Signature`,strokes:{v:1,w:1,h:1,strokes:t.strokes},caption:t.typedName?[t.typedName,...n]:n}:{type:`signature`,label:`Signature`,typedName:t?.typedName??e.name,caption:n}}function Hi(e,t,n){let r=e.envelope.signerFields??[];if(r.length===0)return[];let i=t.fieldValues??{};return[{type:`spacer`,height:12},{type:`heading`,text:`Details entered by ${n?t.name:`the signer`}`,level:2},{type:`table`,columns:[{header:`Field`},{header:`Value`,width:2}],rows:r.map(e=>[e.label,i[e.key]??``])}]}function Ui(e){let{envelope:t,signers:n,events:r,head:i,envelopeId:a}=e,o=n.length>1,s=[[`Envelope`,a],[`Document`,t.title],[`Document SHA-256`,t.docSha256??``],...n.flatMap((e,t)=>[[o?`Signer ${t+1}`:`Signer`,e.name],[`Signing as`,Li[e.as]??e.as],...e.participant?[[`Participant`,e.participant.name]]:[],[`Signature`,e.signature?.kind===`drawn`?`Drawn`:`Typed`],[`Signature SHA-256`,e.signature?.sha256??``],[`Consent version`,e.consentVersion??``],...e.consentSha256?[[`Consent wording SHA-256`,e.consentSha256]]:[],...e.otpVerifiedAt?[[`Identity check`,`Email one-time code verified`]]:[],[`Signed`,Ri(e.signedAt)]]),[`Completed`,Ri(t.completedAt)],[`Audit events`,String(r.length)]],c=r.map(e=>[String(e.seq+1),Ri(e.at),e.type,typeof e.data.signer==`number`?`signer ${e.data.signer}`:e.actor,e.personal?.ip??``,e.hash.slice(0,16)]);return{info:{title:t.title,subject:`Signed document and certificate of completion`,creator:`semics e-sign`,...t.completedAt?{creationDate:new Date(t.completedAt)}:{}},footer:{text:`Envelope ${a}`,pageNumbers:!0},blocks:[{type:`heading`,text:t.title,level:1},...Bi(e.snapshot),...n.flatMap(t=>[...Hi(e,t,o),{type:`spacer`,height:18},Vi(t)]),{type:`pageBreak`},{type:`heading`,text:`Certificate of completion`,level:1},{type:`paragraph`,text:Ii},{type:`spacer`,height:8},{type:`table`,columns:[{header:`Field`},{header:`Value`,width:3}],rows:s},{type:`spacer`,height:8},{type:`heading`,text:`Audit trail`,level:2},{type:`table`,columns:[{header:`#`,width:.4},{header:`Time`,width:1.6},{header:`Event`,width:1.6},{header:`Actor`,width:.8},{header:`IP address`,width:1.2},{header:`Event hash (first 16)`,width:1.6}],rows:c,size:8},{type:`spacer`,height:8},{type:`paragraph`,text:`Audit chain head`,font:`bold`,size:9},{type:`paragraph`,text:i,size:9},{type:`paragraph`,text:`Final hash`,font:`bold`,size:9},{type:`paragraph`,text:t.finalHash??``,size:9}]}}async function Wi(e){let t=bn(Ui(e));return{bytes:t,sha256:await F(t)}}const Gi=new TextEncoder().encode(`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/`);function Ki(e){let t=new Uint8Array(Math.ceil(e.length/3)*4),n=e.length-e.length%3,r=0;for(let i=0;i<n;i+=3){let n=e[i]<<16|e[i+1]<<8|e[i+2];t[r++]=Gi[n>>18],t[r++]=Gi[n>>12&63],t[r++]=Gi[n>>6&63],t[r++]=Gi[n&63]}if(n<e.length){let i=n+1<e.length,a=e[n]<<16|(i?e[n+1]<<8:0);t[r++]=Gi[a>>18],t[r++]=Gi[a>>12&63],t[r++]=i?Gi[a>>6&63]:61,t[r++]=61}return new TextDecoder().decode(t)}function qi(e){try{let t=atob(e),n=new Uint8Array(t.length);for(let e=0;e<t.length;e++)n[e]=t.charCodeAt(e);return n}catch{return null}}const Ji=(e,t,n)=>`${e}:pdf:${t.slice(0,16)}:${n}`;function Yi(e,t,n){let r=Math.max(1,Math.ceil(t.length/Pi));return Array.from({length:r},(i,a)=>({id:Ji(e,n,a),data:{envelopeId:e,kind:Fi,contentType:`application/pdf`,index:a,count:r,bytes:t.length,sha256:n,data:Ki(t.subarray(a*Pi,(a+1)*Pi))}}))}function Xi(e){let t=e[0];if(!t||e.length!==t.count)return null;let n=[...e].sort((e,t)=>e.index-t.index),r=new Uint8Array(t.bytes),i=0;for(let[e,a]of n.entries()){if(a.index!==e||a.sha256!==t.sha256||a.bytes!==t.bytes)return null;let n=qi(a.data);if(!n||i+n.length>r.length)return null;r.set(n,i),i+=n.length}return i===r.length?r:null}const Zi=`signed-pdf-`,Qi=e=>`${Zi}${e}`;function $i(e,t,n,r=0){return e?.schedule(Qi(t),{schedule:N(n),data:{envelopeId:t,attempt:r}})}async function ea(e,t,n){let{envelopes:r,signers:i,snapshots:a,audit_events:o,artifacts:s}=B(e),c=await r.get(t);if(!c||c.status!==`completed`||c.pdfSha256||c.personalPurgedAt||c.signerIds.length===0||!c.snapshot||!c.docSha256)return`skipped`;let[l,u,d]=await Promise.all([i.getMany(c.signerIds),a.getMany(c.snapshot.ids),o.query({where:{envelopeId:t},orderBy:{seq:`asc`},limit:100})]),f=ri([...u.values()]),p=d.items.map(e=>e.data),m=await br(t,p),h=m.ok&&p.at(-1)?.type===`envelope.completed`&&await Sr(c.docSha256,m.value.head)===c.finalHash,g=c.signerIds.map(e=>l.get(e));if(g.some(e=>e?.status!==`signed`)||f===null||!m.ok||!h){let r=n.attempt??0;return r+1>=5?(e.log.error(`signed PDF not generated: the envelope never settled`,{envelopeId:t}),`gave-up`):(await $i(e.cron,t,n.now+6e4,r+1),`retry`)}let{bytes:_,sha256:v}=await Wi({envelopeId:t,envelope:c,signers:g,snapshot:f,events:p,head:m.value.head}),y=Yi(t,_,v);return await s.putMany(y),(await r.updateIf(t,{where:{status:`completed`,pdfSha256:null},set:{pdfSha256:v,pdf:{ids:y.map(e=>e.id),bytes:_.length},updatedAt:N(n.now)}})).applied?(await Na(e.cron,t,n.now),`stored`):`skipped`}async function ta(e,t){if(!e.name.startsWith(Zi))return!1;let n=e.data?.envelopeId,r=e.data?.attempt;return typeof n!=`string`||n.length===0||await ea(t,n,{now:Date.now(),attempt:typeof r==`number`&&Number.isSafeInteger(r)?r:0}),!0}const na=`esign/download`,ra=`esign:download-link-key`,ia=/^[A-Za-z0-9_:.-]{1,200}$/,aa=RegExp(`^[0-9a-f]{64}$`);function oa(e){return typeof e!=`string`||!aa.test(e)?null:Uint8Array.from(e.match(/../g),e=>Number.parseInt(e,16))}async function sa(e){let t=oa(await e.get(ra));if(t)return t;let n=crypto.getRandomValues(new Uint8Array(32));if((await e.compareAndSet(ra,null,D(n))).applied)return n;let r=oa(await e.get(ra));if(!r)throw Error(`download link key unavailable`);return r}async function ca(e,t,n){let r=await ye({secret:await sa(e.kv),purpose:na,params:{e:t},now:n,ttlMs:9e5}),i=N(Number(r.get(`exp`))*1e3);return{url:`/_emdash/api/plugins/${e.plugin.id}/public/download?${r}`,expiresAt:i}}function la(e){let{status:t,body:n}=oe(e);return ui({status:t,headers:{"content-type":`application/json; charset=utf-8`,"cache-control":`no-store`},body:{kind:`text`,value:JSON.stringify(n)}})}function ua(e){try{return e?.url?new URL(e.url).searchParams:null}catch{return null}}async function da(e,t){let n=ua(e.request);if(!n)return la(`TOKEN_INVALID`);if(n.has(`token`))return la(`TOKEN_IN_QUERY`);let r=Date.now(),i=await be({secret:await sa(t.kv),purpose:na,query:n,now:r});if(!i.ok)return la(i.error);let a=i.value.e;if(typeof a!=`string`||!ia.test(a))return la(`TOKEN_INVALID`);let{envelopes:o,artifacts:s}=B(t),c=await o.get(a);if(!c||c.status!==`completed`||c.recordsPurgedAt)return la(`ENVELOPE_NOT_FOUND`);if(!c.pdfSha256||!c.pdf)return await $i(t.cron,a,r),la(`SIGNED_PDF_PENDING`);let l=Xi([...(await s.getMany(c.pdf.ids)).values()]);return!l||await F(l)!==c.pdfSha256?(t.log.error(`signed PDF chunks do not match pdfSha256`,{envelopeId:a}),la(`INTERNAL`)):ui({status:200,headers:{"content-type":`application/pdf`,"content-disposition":`attachment; filename="signed-${a.replace(/[^A-Za-z0-9_-]/g,`_`)}.pdf"`,"cache-control":`private, no-store`,"x-content-type-options":`nosniff`,"referrer-policy":`no-referrer`},body:{kind:`bytes`,value:l}})}const fa=(e,t)=>da(e,t),pa=e=>typeof e.user?.id==`string`&&e.user.id.length>0?e.user.id:void 0,B=e=>e.storage,V=e=>typeof e==`object`&&e?e:{},H=e=>({...oe(`BAD_REQUEST`).body,...e?{issues:e}:{}}),U=e=>oe(e).body;function ma(e){let t=V(e).id;return typeof t==`string`&&t.length>0&&t.length<=200?t:null}function ha(e){return Number.isSafeInteger(e)&&e>=1&&e<=365?e:30}function ga(e){return e instanceof Error&&e.message.includes(`UNIQUE constraint failed`)}async function _a(e,t,n){let r=e;for(let e=1;;e++)try{return{token:r,value:await n(await j(r))}}catch(n){if(!ga(n)||e>=3)throw n;r=A(t)}}async function va(e,t,n,r){let{token:i}=await _a(n,r,n=>e.put(t.id,{...t.data,tokenHash:n}));return i}const ya=(e,{piiSalt:t,...n})=>({id:e,...n}),ba=(e,{snapshot:t,fieldValues:n,piiSalt:r,...i})=>({id:e,...i});async function xa(e,t,n,r){if(!(await gr(B(e).audit_events,t,r,{salt:n.piiSalt})).ok)throw Error(`audit chain contention`)}async function Sa(e,t){let n=Kr(e.input);if(!n.ok)return H(n.error);let{templateId:r,templateVersion:i}=n.value,{templates:a,envelopes:o,audit_events:s}=B(t),c=await a.getMany(i===void 0?[r]:[r,z(r,i)]),l=qr(c.get(r),i===void 0?void 0:c.get(z(r,i)),i);if(!l.ok)return U(`TEMPLATE_NOT_FOUND`);let u=cr(),d=Zr(n.value,l.value,{now:N(),piiSalt:u});if(!d.ok)return H(d.error);let f=crypto.randomUUID();return await o.put(f,d.value),await s.putMany(await mr(f,[ci(d.value,`admin`,pa(e))],u)),{ok:!0,envelope:ya(f,d.value)}}let Ca;const wa=e=>{Ca=e};async function Ta(e,t){let n=ma(e.input);if(!n)return H();let{envelopes:r,templates:i,snapshots:a,signers:o}=B(t),s=await r.get(n);if(!s)return U(`ENVELOPE_NOT_FOUND`);if(!Dr(s.status,`sent`))return U(`ENVELOPE_CLOSED`);let{templateId:c,templateVersion:l}=s,[u,d]=await Promise.all([i.getMany([c,z(c,l)]),t.settings.list()]),f=Object.fromEntries(d.map(e=>[e.key,e.value])),p=qr(u.get(c),u.get(z(c,l)),l);if(!p.ok)return U(`TEMPLATE_NOT_FOUND`);let m=A(),h=await ii(n,{...s,...await Ca?.(t,f,p.value)},p.value,{now:N(),tokenHash:await j(m),expiryDays:ha(f.expiryDays)});if(!h.ok)return Array.isArray(h.error)?H(h.error):U(`ENVELOPE_CLOSED`);await a.putMany(h.value.chunks);let g=await R(r,n,`draft`,`sent`,h.value.envelope);if(!g.ok)return U(`ENVELOPE_CLOSED`);let _=await va(o,h.value.signer,m),v=await rr(t,{signerId:h.value.signer.id,envelope:g.value,token:_,senderSetting:f.senderName,now:Date.now()});return await xa(t,n,g.value,li(g.value,`admin`,pa(e))),{ok:!0,envelope:ya(n,g.value),...v?{}:{invitation:`SITE_URL_MISSING`}}}async function Ea(e,t){let n=ma(e.input);if(!n)return H();let{envelopes:r,snapshots:i,signers:a}=B(t),o=await r.get(n);if(!o)return U(`ENVELOPE_NOT_FOUND`);let[s,c]=await Promise.all([o.snapshot?i.getMany(o.snapshot.ids):Promise.resolve(new Map),o.signerIds.length>0?a.getMany(o.signerIds):Promise.resolve(new Map)]),l=o.pdfSha256?await ca(t,n,Date.now()):null;return{ok:!0,envelope:ya(n,o),download:l,snapshot:o.snapshot?ri([...s.values()]):null,signers:[...c].map(([e,t])=>({id:e,order:t.order,name:t.name,email:t.email,status:t.status}))}}async function Da(e,t){let n=ma(e.input);if(!n)return H();let{envelopes:r,signers:i,outbox:a,audit_events:o}=B(t),s=await r.get(n);if(!s)return U(`ENVELOPE_NOT_FOUND`);let c=s.signerIds[0];if(s.status!==`sent`||c===void 0)return U(`ENVELOPE_CLOSED`);if(!L(t))return{ok:!1,error:{code:`SITE_URL_MISSING`,message:nr}};let l=ur(n,0),u=ur(n,1),[d,f,p]=await Promise.all([t.settings.get(`senderName`),a.get(`invite-${c}`),o.getMany([l,u])]);if(f&&f.status!==`failed`)return{ok:!1,error:{code:`INVITATION_QUEUED`,message:`The invitation is already queued or sent.`}};let m=await _a(A(),void 0,e=>i.updateIf(c,{where:{status:`pending`},set:{tokenHash:e}}));if(!m.value.applied)return U(`ENVELOPE_CLOSED`);await rr(t,{signerId:c,envelope:s,token:m.token,senderSetting:d,now:Date.now()});let h=!1;p.has(u)||(h=await vr(o,await hr(n,p.get(l)??null,[li(s,`admin`,pa(e))],s.piiSalt)));let{name:g,email:_,status:v}=m.value.data;return{ok:!0,envelope:ya(n,s),signers:[{id:c,order:m.value.data.order,name:g,email:_,status:v}],repaired:h}}async function Oa(e,t){let n=ma(e.input);if(!n)return H();let r=await B(t).envelopes.get(n);if(!r)return U(`ENVELOPE_NOT_FOUND`);let i=N(),a=await R(B(t).envelopes,n,r.status,`voided`,{closedAt:i,updatedAt:i});return a.ok?(await xa(t,n,a.value,{type:`envelope.voided`,at:i,actor:`admin`,...pa(e)?{data:{userId:pa(e)}}:{}}),{ok:!0,envelope:ya(n,a.value)}):U(`ENVELOPE_CLOSED`)}async function ka(e,t){let{status:n,cursor:r}=V(e.input);if(n!==void 0&&!Er(n)||r!==void 0&&!(typeof r==`string`&&r.length>0&&r.length<=500))return H();let i=await B(t).envelopes.query({...n===void 0?{}:{where:{status:n}},orderBy:{createdAt:`desc`},limit:100,...r===void 0?{}:{cursor:r}});return{ok:!0,envelopes:i.items.map(e=>ba(e.id,e.data)),...i.hasMore&&i.cursor?{nextCursor:i.cursor}:{}}}const Aa={"envelopes/create":{handler:Sa},"envelopes/send":{handler:Ta},"envelopes/get":{handler:Ea},"envelopes/list":{handler:ka},"envelopes/resend":{handler:Da},"envelopes/void":{handler:Oa},"outbox/status":{handler:(async(e,t)=>({ok:!0,...await or(t)}))}},ja=`completion-email-`,Ma=e=>`${ja}${e}`;function Na(e,t,n){return e?.schedule(Ma(t),{schedule:N(n),data:{envelopeId:t}})}async function Pa(e,t,n){let[r,i,a]=await Promise.all([B(e).envelopes.get(t),e.settings.get(`senderName`),B(e).outbox.get(`complete-${t}`)]);if(!r||r.status!==`completed`||!r.pdfSha256||a)return!1;let o=r.signerIds[0];if(o===void 0||!L(e))return!1;let s=await _a(A(),void 0,t=>B(e).signers.updateIf(o,{where:{status:`signed`},set:{copyTokenHash:t}}));return s.value.applied?(await ir(e,{envelopeId:t,envelope:r,token:s.token,senderSetting:i,now:n}),!0):!1}async function Fa(e,t){if(!e.name.startsWith(ja))return!1;let n=e.data?.envelopeId;return typeof n==`string`&&n.length>0&&await Pa(t,n,Date.now()),!0}const Ia=/^[0-9a-f]{64}$/,La=/[\u0000-\u001F\u007F]/,Ra=e=>Array.isArray(e)&&e.length===2&&e.every(e=>typeof e==`number`&&Number.isFinite(e)&&e>=0&&e<=1);function za(e){let t=e=>k({path:`signature.strokes`,code:e});return!Array.isArray(e)||e.length===0||e.length>64?t(`INVALID_SIGNATURE`):JSON.stringify(e).length>32768?t(`STROKES_TOO_LARGE`):e.every(e=>Array.isArray(e)&&e.length>0&&e.every(Ra))?O(e):t(`INVALID_SIGNATURE`)}function Ba(e){let t=k({path:`signature`,code:`INVALID_SIGNATURE`});if(!Br(e)||e.kind!==`typed`&&e.kind!==`drawn`)return t;let n=e.typedName===void 0?void 0:Hr(e.typedName);if(n===null)return t;if(e.kind===`typed`)return n===void 0?t:O({kind:`typed`,typedName:n});let r=za(e.strokes);return r.ok?O({kind:`drawn`,...n===void 0?{}:{typedName:n},strokes:r.value}):r}function Va(e){if(!Br(e))return k([{path:``,code:`INVALID_INPUT`}]);let t=[];e.consent!==!0&&t.push({path:`consent`,code:`CONSENT_REQUIRED`}),e.intent!==!0&&t.push({path:`intent`,code:`INTENT_REQUIRED`});let n=typeof e.docSha256==`string`&&Ia.test(e.docSha256)?e.docSha256:null;n===null&&t.push({path:`docSha256`,code:`INVALID_DOC_HASH`});let r=typeof e.consentSha256==`string`&&Ia.test(e.consentSha256)?e.consentSha256:null;r===null&&t.push({path:`consentSha256`,code:`INVALID_CONSENT_HASH`});let i=Ba(e.signature);i.ok||t.push(i.error);let a=Wr(e.fieldValues);return a===null&&t.push({path:`fieldValues`,code:`INVALID_FIELDS`}),t.length>0||n===null||r===null||!i.ok||a===null?k(t):O({docSha256:n,consentSha256:r,signature:i.value,fieldValues:a})}function Ha(e){if(e===void 0)return;let t=typeof e==`string`?e.trim():``;return t.length===0||[...t].length>500||La.test(t)?null:t}async function Ua(e,t,n){let r=Object.keys(n.fieldValues).sort().map(e=>[e,n.fieldValues[e]]),i=await F(n.salt+JSON.stringify([e,t.kind,t.typedName??null,t.strokes??null,r]));return{...t,sha256:i}}const Wa=e=>({...e.ip===void 0?{}:{ip:e.ip},...e.ua===void 0?{}:{ua:e.ua}}),Ga=e=>e===void 0?{}:{signer:e};function Ka(e,t,n,r){return{type:`signer.viewed`,at:e,actor:`signer`,data:{docSha256:t,...Ga(r)},personal:Wa(n)}}function qa(e){let{at:t,docSha256:n,signature:r}=e;return[{type:`signer.consented`,at:t,actor:`signer`,data:{docSha256:n,consentVersion:e.consentVersion,consentSha256:e.consentSha256,intent:!0},personal:Wa(e.who)},{type:`signer.signed`,at:t,actor:`signer`,data:{docSha256:n,kind:r.kind,signatureSha256:r.sha256},personal:{name:r.typedName??e.signerName,...Wa(e.who)}},{type:`envelope.completed`,at:t,actor:`system`,data:{docSha256:n}}]}function Ja(e){let{at:t,docSha256:n,hasReason:r}=e;return[{type:`signer.declined`,at:t,actor:`signer`,data:{docSha256:n,hasReason:r,...Ga(e.order)},personal:Wa(e.who)},{type:`envelope.declined`,at:t,actor:`system`,data:{docSha256:n}}]}function Ya(e){let t=e.startsWith(``)?e.slice(1):e,n=[],r=[],i=``,a=!1,o=!1,s=1,c=1,l=()=>{r.push(i),i=``,o=!1},u=()=>{l(),(r.length>1||r[0]!==``||o)&&n.push({line:c,cells:r}),r=[],c=s};for(let e=0;e<t.length;e++){let n=t.charAt(e);a?n===`"`?t.charAt(e+1)===`"`?(i+=`"`,e++):a=!1:(n===`
36
+ `),0)}const z=262144/4*3,Fi=`signed-pdf`,Ii=`This certificate records how the document above was signed. It was signed with a simple electronic signature: the signer consented to sign electronically, confirmed their intent to sign, and signed the exact text identified by the document SHA-256 below. Every step is recorded in a hash-chained audit trail; the final hash binds the document to the end of that trail. Anyone holding this PDF can check these values on the verify page.`,Li={self:`Self`,guardian:`Parent or guardian`,buyer:`Buyer`},Ri=e=>e?`${e.slice(0,10)} ${e.slice(11,19)} UTC`:``;function zi(e){return e.map(e=>{switch(e.type){case`text`:case`code`:return e.text;case`break`:return`
37
+ `;case`link`:{let t=zi(e.children);return t===e.href?t:`${t} (${e.href})`}default:return zi(e.children)}}).join(``)}function Bi(e){let t=[],n=(e,r)=>{for(let i of e)switch(i.type){case`heading`:t.push({type:`heading`,text:zi(i.children),level:Math.min(i.level,3)});break;case`paragraph`:t.push({type:`paragraph`,text:zi(i.children),...r?{font:`italic`}:{}});break;case`list`:i.items.forEach((e,n)=>{let a=i.ordered?`${(i.start??1)+n}.`:`•`;t.push({type:`paragraph`,text:`${a} ${zi(e)}`,...r?{font:`italic`}:{}})});break;case`quote`:n(i.children,!0);break;case`code`:t.push({type:`paragraph`,text:i.text,size:9});break;case`rule`:t.push({type:`rule`});break}};return n(Pi(e),!1),t}function Vi(e){let t=e.signature,n=[e.name,`Signed ${Ri(e.signedAt)}`];return t?.kind===`drawn`&&t.strokes?{type:`signature`,label:`Signature`,strokes:{v:1,w:1,h:1,strokes:t.strokes},caption:t.typedName?[t.typedName,...n]:n}:{type:`signature`,label:`Signature`,typedName:t?.typedName??e.name,caption:n}}function Hi(e,t,n){let r=e.envelope.signerFields??[];if(r.length===0)return[];let i=t.fieldValues??{};return[{type:`spacer`,height:12},{type:`heading`,text:`Details entered by ${n?t.name:`the signer`}`,level:2},{type:`table`,columns:[{header:`Field`},{header:`Value`,width:2}],rows:r.map(e=>[e.label,i[e.key]??``])}]}function Ui(e){let{envelope:t,signers:n,events:r,head:i,envelopeId:a}=e,o=n.length>1,s=[[`Envelope`,a],[`Document`,t.title],[`Document SHA-256`,t.docSha256??``],...n.flatMap((e,t)=>[[o?`Signer ${t+1}`:`Signer`,e.name],[`Signing as`,Li[e.as]??e.as],...e.participant?[[`Participant`,e.participant.name]]:[],[`Signature`,e.signature?.kind===`drawn`?`Drawn`:`Typed`],[`Signature SHA-256`,e.signature?.sha256??``],[`Consent version`,e.consentVersion??``],...e.consentSha256?[[`Consent wording SHA-256`,e.consentSha256]]:[],...e.otpVerifiedAt?[[`Identity check`,`Email one-time code verified`]]:[],[`Signed`,Ri(e.signedAt)]]),[`Completed`,Ri(t.completedAt)],[`Audit events`,String(r.length)]],c=r.map(e=>[String(e.seq+1),Ri(e.at),e.type,typeof e.data.signer==`number`?`signer ${e.data.signer}`:e.actor,e.personal?.ip??``,e.hash.slice(0,16)]);return{info:{title:t.title,subject:`Signed document and certificate of completion`,creator:`semics e-sign`,...t.completedAt?{creationDate:new Date(t.completedAt)}:{}},footer:{text:`Envelope ${a}`,pageNumbers:!0},blocks:[{type:`heading`,text:t.title,level:1},...Bi(e.snapshot),...n.flatMap(t=>[...Hi(e,t,o),{type:`spacer`,height:18},Vi(t)]),{type:`pageBreak`},{type:`heading`,text:`Certificate of completion`,level:1},{type:`paragraph`,text:Ii},{type:`spacer`,height:8},{type:`table`,columns:[{header:`Field`},{header:`Value`,width:3}],rows:s},{type:`spacer`,height:8},{type:`heading`,text:`Audit trail`,level:2},{type:`table`,columns:[{header:`#`,width:.4},{header:`Time`,width:1.6},{header:`Event`,width:1.6},{header:`Actor`,width:.8},{header:`IP address`,width:1.2},{header:`Event hash (first 16)`,width:1.6}],rows:c,size:8},{type:`spacer`,height:8},{type:`paragraph`,text:`Audit chain head`,font:`bold`,size:9},{type:`paragraph`,text:i,size:9},{type:`paragraph`,text:`Final hash`,font:`bold`,size:9},{type:`paragraph`,text:t.finalHash??``,size:9}]}}async function Wi(e){let t=bn(Ui(e));return{bytes:t,sha256:await F(t)}}const Gi=new TextEncoder().encode(`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/`);function Ki(e){let t=new Uint8Array(Math.ceil(e.length/3)*4),n=e.length-e.length%3,r=0;for(let i=0;i<n;i+=3){let n=e[i]<<16|e[i+1]<<8|e[i+2];t[r++]=Gi[n>>18],t[r++]=Gi[n>>12&63],t[r++]=Gi[n>>6&63],t[r++]=Gi[n&63]}if(n<e.length){let i=n+1<e.length,a=e[n]<<16|(i?e[n+1]<<8:0);t[r++]=Gi[a>>18],t[r++]=Gi[a>>12&63],t[r++]=i?Gi[a>>6&63]:61,t[r++]=61}return new TextDecoder().decode(t)}function qi(e){try{let t=atob(e),n=new Uint8Array(t.length);for(let e=0;e<t.length;e++)n[e]=t.charCodeAt(e);return n}catch{return null}}const Ji=(e,t,n)=>`${e}:pdf:${t.slice(0,16)}:${n}`;function Yi(e,t,n){let r=Math.max(1,Math.ceil(t.length/z));return Array.from({length:r},(i,a)=>({id:Ji(e,n,a),data:{envelopeId:e,kind:Fi,contentType:`application/pdf`,index:a,count:r,bytes:t.length,sha256:n,data:Ki(t.subarray(a*z,(a+1)*z))}}))}function Xi(e){let t=e[0];if(!t||e.length!==t.count)return null;let n=[...e].sort((e,t)=>e.index-t.index),r=new Uint8Array(t.bytes),i=0;for(let[e,a]of n.entries()){if(a.index!==e||a.sha256!==t.sha256||a.bytes!==t.bytes)return null;let n=qi(a.data);if(!n||i+n.length>r.length)return null;r.set(n,i),i+=n.length}return i===r.length?r:null}const Zi=`signed-pdf-`,Qi=e=>`${Zi}${e}`;function $i(e,t,n,r=0){return e?.schedule(Qi(t),{schedule:N(n),data:{envelopeId:t,attempt:r}})}async function ea(e,t,n){let{envelopes:r,signers:i,snapshots:a,audit_events:o,artifacts:s}=B(e),c=await r.get(t);if(!c||c.status!==`completed`||c.pdfSha256||c.personalPurgedAt||c.signerIds.length===0||!c.snapshot||!c.docSha256)return`skipped`;let[l,u,d]=await Promise.all([i.getMany(c.signerIds),a.getMany(c.snapshot.ids),o.query({where:{envelopeId:t},orderBy:{seq:`asc`},limit:100})]),f=ii([...u.values()]),p=d.items.map(e=>e.data),m=await br(t,p),h=m.ok&&p.at(-1)?.type===`envelope.completed`&&await Sr(c.docSha256,m.value.head)===c.finalHash,g=c.signerIds.map(e=>l.get(e));if(g.some(e=>e?.status!==`signed`)||f===null||!m.ok||!h){let r=n.attempt??0;return r+1>=5?(e.log.error(`signed PDF not generated: the envelope never settled`,{envelopeId:t}),`gave-up`):(await $i(e.cron,t,n.now+6e4,r+1),`retry`)}let{bytes:_,sha256:v}=await Wi({envelopeId:t,envelope:c,signers:g,snapshot:f,events:p,head:m.value.head}),y=Yi(t,_,v);return await s.putMany(y),(await r.updateIf(t,{where:{status:`completed`,pdfSha256:null},set:{pdfSha256:v,pdf:{ids:y.map(e=>e.id),bytes:_.length},updatedAt:N(n.now)}})).applied?(await Na(e.cron,t,n.now),`stored`):`skipped`}async function ta(e,t){if(!e.name.startsWith(Zi))return!1;let n=e.data?.envelopeId,r=e.data?.attempt;return typeof n!=`string`||n.length===0||await ea(t,n,{now:Date.now(),attempt:typeof r==`number`&&Number.isSafeInteger(r)?r:0}),!0}const na=`esign/download`,ra=`esign:download-link-key`,ia=/^[A-Za-z0-9_:.-]{1,200}$/,aa=RegExp(`^[0-9a-f]{64}$`);function oa(e){return typeof e!=`string`||!aa.test(e)?null:Uint8Array.from(e.match(/../g),e=>Number.parseInt(e,16))}async function sa(e){let t=oa(await e.get(ra));if(t)return t;let n=crypto.getRandomValues(new Uint8Array(32));if((await e.compareAndSet(ra,null,D(n))).applied)return n;let r=oa(await e.get(ra));if(!r)throw Error(`download link key unavailable`);return r}async function ca(e,t,n){let r=await ye({secret:await sa(e.kv),purpose:na,params:{e:t},now:n,ttlMs:9e5}),i=N(Number(r.get(`exp`))*1e3);return{url:`/_emdash/api/plugins/${e.plugin.id}/public/download?${r}`,expiresAt:i}}function la(e){let{status:t,body:n}=oe(e);return di({status:t,headers:{"content-type":`application/json; charset=utf-8`,"cache-control":`no-store`},body:{kind:`text`,value:JSON.stringify(n)}})}function ua(e){try{return e?.url?new URL(e.url).searchParams:null}catch{return null}}async function da(e,t){let n=ua(e.request);if(!n)return la(`TOKEN_INVALID`);if(n.has(`token`))return la(`TOKEN_IN_QUERY`);let r=Date.now(),i=await be({secret:await sa(t.kv),purpose:na,query:n,now:r});if(!i.ok)return la(i.error);let a=i.value.e;if(typeof a!=`string`||!ia.test(a))return la(`TOKEN_INVALID`);let{envelopes:o,artifacts:s}=B(t),c=await o.get(a);if(!c||c.status!==`completed`||c.recordsPurgedAt)return la(`ENVELOPE_NOT_FOUND`);if(!c.pdfSha256||!c.pdf)return await $i(t.cron,a,r),la(`SIGNED_PDF_PENDING`);let l=Xi([...(await s.getMany(c.pdf.ids)).values()]);return!l||await F(l)!==c.pdfSha256?(t.log.error(`signed PDF chunks do not match pdfSha256`,{envelopeId:a}),la(`INTERNAL`)):di({status:200,headers:{"content-type":`application/pdf`,"content-disposition":`attachment; filename="signed-${a.replace(/[^A-Za-z0-9_-]/g,`_`)}.pdf"`,"cache-control":`private, no-store`,"x-content-type-options":`nosniff`,"referrer-policy":`no-referrer`},body:{kind:`bytes`,value:l}})}const fa=(e,t)=>da(e,t),pa=e=>typeof e.user?.id==`string`&&e.user.id.length>0?e.user.id:void 0,B=e=>e.storage,V=e=>typeof e==`object`&&e?e:{},H=e=>({...oe(`BAD_REQUEST`).body,...e?{issues:e}:{}}),U=e=>oe(e).body;function ma(e){let t=V(e).id;return typeof t==`string`&&t.length>0&&t.length<=200?t:null}function ha(e){return Number.isSafeInteger(e)&&e>=1&&e<=365?e:30}function ga(e){return e instanceof Error&&e.message.includes(`UNIQUE constraint failed`)}async function _a(e,t,n){let r=e;for(let e=1;;e++)try{return{token:r,value:await n(await j(r))}}catch(n){if(!ga(n)||e>=3)throw n;r=A(t)}}async function va(e,t,n,r){let{token:i}=await _a(n,r,n=>e.put(t.id,{...t.data,tokenHash:n}));return i}const ya=(e,{piiSalt:t,...n})=>({id:e,...n}),ba=(e,{snapshot:t,fieldValues:n,piiSalt:r,...i})=>({id:e,...i});async function xa(e,t,n,r){if(!(await gr(B(e).audit_events,t,r,{salt:n.piiSalt})).ok)throw Error(`audit chain contention`)}async function Sa(e,t){let n=qr(e.input);if(!n.ok)return H(n.error);let{templateId:r,templateVersion:i}=n.value,{templates:a,envelopes:o,audit_events:s}=B(t),c=await a.getMany(i===void 0?[r]:[r,R(r,i)]),l=Jr(c.get(r),i===void 0?void 0:c.get(R(r,i)),i);if(!l.ok)return U(`TEMPLATE_NOT_FOUND`);let u=cr(),d=Qr(n.value,l.value,{now:N(),piiSalt:u});if(!d.ok)return H(d.error);let f=crypto.randomUUID();return await o.put(f,d.value),await s.putMany(await mr(f,[li(d.value,`admin`,pa(e))],u)),{ok:!0,envelope:ya(f,d.value)}}let Ca;const wa=e=>{Ca=e};async function Ta(e,t){let n=ma(e.input);if(!n)return H();let{envelopes:r,templates:i,snapshots:a,signers:o}=B(t),s=await r.get(n);if(!s)return U(`ENVELOPE_NOT_FOUND`);if(!Dr(s.status,`sent`))return U(`ENVELOPE_CLOSED`);let{templateId:c,templateVersion:l}=s,[u,d]=await Promise.all([i.getMany([c,R(c,l)]),t.settings.list()]),f=Object.fromEntries(d.map(e=>[e.key,e.value])),p=Jr(u.get(c),u.get(R(c,l)),l);if(!p.ok)return U(`TEMPLATE_NOT_FOUND`);let m=A(),h=await ai(n,{...s,...await Ca?.(t,f,p.value)},p.value,{now:N(),tokenHash:await j(m),expiryDays:ha(f.expiryDays)});if(!h.ok)return Array.isArray(h.error)?H(h.error):U(`ENVELOPE_CLOSED`);await a.putMany(h.value.chunks);let g=await kr(r,n,`draft`,`sent`,h.value.envelope);if(!g.ok)return U(`ENVELOPE_CLOSED`);let _=await va(o,h.value.signer,m),v=await rr(t,{signerId:h.value.signer.id,envelope:g.value,token:_,senderSetting:f.senderName,now:Date.now()});return await xa(t,n,g.value,ui(g.value,`admin`,pa(e))),{ok:!0,envelope:ya(n,g.value),...v?{}:{invitation:`SITE_URL_MISSING`}}}async function Ea(e,t){let n=ma(e.input);if(!n)return H();let{envelopes:r,snapshots:i,signers:a}=B(t),o=await r.get(n);if(!o)return U(`ENVELOPE_NOT_FOUND`);let[s,c]=await Promise.all([o.snapshot?i.getMany(o.snapshot.ids):Promise.resolve(new Map),o.signerIds.length>0?a.getMany(o.signerIds):Promise.resolve(new Map)]),l=o.pdfSha256?await ca(t,n,Date.now()):null;return{ok:!0,envelope:ya(n,o),download:l,snapshot:o.snapshot?ii([...s.values()]):null,signers:[...c].map(([e,t])=>({id:e,order:t.order,name:t.name,email:t.email,status:t.status}))}}async function Da(e,t){let n=ma(e.input);if(!n)return H();let{envelopes:r,signers:i,outbox:a,audit_events:o}=B(t),s=await r.get(n);if(!s)return U(`ENVELOPE_NOT_FOUND`);let c=s.signerIds[0];if(s.status!==`sent`||c===void 0)return U(`ENVELOPE_CLOSED`);if(!L(t))return{ok:!1,error:{code:`SITE_URL_MISSING`,message:nr}};let l=ur(n,0),u=ur(n,1),[d,f,p]=await Promise.all([t.settings.get(`senderName`),a.get(`invite-${c}`),o.getMany([l,u])]);if(f&&f.status!==`failed`)return{ok:!1,error:{code:`INVITATION_QUEUED`,message:`The invitation is already queued or sent.`}};let m=await _a(A(),void 0,e=>i.updateIf(c,{where:{status:`pending`},set:{tokenHash:e}}));if(!m.value.applied)return U(`ENVELOPE_CLOSED`);await rr(t,{signerId:c,envelope:s,token:m.token,senderSetting:d,now:Date.now()});let h=!1;p.has(u)||(h=await vr(o,await hr(n,p.get(l)??null,[ui(s,`admin`,pa(e))],s.piiSalt)));let{name:g,email:_,status:v}=m.value.data;return{ok:!0,envelope:ya(n,s),signers:[{id:c,order:m.value.data.order,name:g,email:_,status:v}],repaired:h}}async function Oa(e,t){let n=ma(e.input);if(!n)return H();let r=await B(t).envelopes.get(n);if(!r)return U(`ENVELOPE_NOT_FOUND`);let i=N(),a=await kr(B(t).envelopes,n,r.status,`voided`,{closedAt:i,updatedAt:i});return a.ok?(await xa(t,n,a.value,{type:`envelope.voided`,at:i,actor:`admin`,...pa(e)?{data:{userId:pa(e)}}:{}}),{ok:!0,envelope:ya(n,a.value)}):U(`ENVELOPE_CLOSED`)}async function ka(e,t){let{status:n,cursor:r}=V(e.input);if(n!==void 0&&!Er(n)||r!==void 0&&!(typeof r==`string`&&r.length>0&&r.length<=500))return H();let i=await B(t).envelopes.query({...n===void 0?{}:{where:{status:n}},orderBy:{createdAt:`desc`},limit:100,...r===void 0?{}:{cursor:r}});return{ok:!0,envelopes:i.items.map(e=>ba(e.id,e.data)),...i.hasMore&&i.cursor?{nextCursor:i.cursor}:{}}}const Aa={"envelopes/create":{handler:Sa},"envelopes/send":{handler:Ta},"envelopes/get":{handler:Ea},"envelopes/list":{handler:ka},"envelopes/resend":{handler:Da},"envelopes/void":{handler:Oa},"outbox/status":{handler:(async(e,t)=>({ok:!0,...await or(t)}))}},ja=`completion-email-`,Ma=e=>`${ja}${e}`;function Na(e,t,n){return e?.schedule(Ma(t),{schedule:N(n),data:{envelopeId:t}})}async function Pa(e,t,n){let[r,i,a]=await Promise.all([B(e).envelopes.get(t),e.settings.get(`senderName`),B(e).outbox.get(`complete-${t}`)]);if(!r||r.status!==`completed`||!r.pdfSha256||a)return!1;let o=r.signerIds[0];if(o===void 0||!L(e))return!1;let s=await _a(A(),void 0,t=>B(e).signers.updateIf(o,{where:{status:`signed`},set:{copyTokenHash:t}}));return s.value.applied?(await ir(e,{envelopeId:t,envelope:r,token:s.token,senderSetting:i,now:n}),!0):!1}async function Fa(e,t){if(!e.name.startsWith(ja))return!1;let n=e.data?.envelopeId;return typeof n==`string`&&n.length>0&&await Pa(t,n,Date.now()),!0}const Ia=/^[0-9a-f]{64}$/,La=/[\u0000-\u001F\u007F]/,Ra=e=>Array.isArray(e)&&e.length===2&&e.every(e=>typeof e==`number`&&Number.isFinite(e)&&e>=0&&e<=1);function za(e){let t=e=>k({path:`signature.strokes`,code:e});return!Array.isArray(e)||e.length===0||e.length>64?t(`INVALID_SIGNATURE`):JSON.stringify(e).length>32768?t(`STROKES_TOO_LARGE`):e.every(e=>Array.isArray(e)&&e.length>0&&e.every(Ra))?O(e):t(`INVALID_SIGNATURE`)}function Ba(e){let t=k({path:`signature`,code:`INVALID_SIGNATURE`});if(!Vr(e)||e.kind!==`typed`&&e.kind!==`drawn`)return t;let n=e.typedName===void 0?void 0:Ur(e.typedName);if(n===null)return t;if(e.kind===`typed`)return n===void 0?t:O({kind:`typed`,typedName:n});let r=za(e.strokes);return r.ok?O({kind:`drawn`,...n===void 0?{}:{typedName:n},strokes:r.value}):r}function Va(e){if(!Vr(e))return k([{path:``,code:`INVALID_INPUT`}]);let t=[];e.consent!==!0&&t.push({path:`consent`,code:`CONSENT_REQUIRED`}),e.intent!==!0&&t.push({path:`intent`,code:`INTENT_REQUIRED`});let n=typeof e.docSha256==`string`&&Ia.test(e.docSha256)?e.docSha256:null;n===null&&t.push({path:`docSha256`,code:`INVALID_DOC_HASH`});let r=typeof e.consentSha256==`string`&&Ia.test(e.consentSha256)?e.consentSha256:null;r===null&&t.push({path:`consentSha256`,code:`INVALID_CONSENT_HASH`});let i=Ba(e.signature);i.ok||t.push(i.error);let a=Gr(e.fieldValues);return a===null&&t.push({path:`fieldValues`,code:`INVALID_FIELDS`}),t.length>0||n===null||r===null||!i.ok||a===null?k(t):O({docSha256:n,consentSha256:r,signature:i.value,fieldValues:a})}function Ha(e){if(e===void 0)return;let t=typeof e==`string`?e.trim():``;return t.length===0||[...t].length>500||La.test(t)?null:t}async function Ua(e,t,n){let r=Object.keys(n.fieldValues).sort().map(e=>[e,n.fieldValues[e]]),i=await F(n.salt+JSON.stringify([e,t.kind,t.typedName??null,t.strokes??null,r]));return{...t,sha256:i}}const Wa=e=>({...e.ip===void 0?{}:{ip:e.ip},...e.ua===void 0?{}:{ua:e.ua}}),Ga=e=>e===void 0?{}:{signer:e};function Ka(e,t,n,r){return{type:`signer.viewed`,at:e,actor:`signer`,data:{docSha256:t,...Ga(r)},personal:Wa(n)}}function qa(e){let{at:t,docSha256:n,signature:r}=e;return[{type:`signer.consented`,at:t,actor:`signer`,data:{docSha256:n,consentVersion:e.consentVersion,consentSha256:e.consentSha256,intent:!0},personal:Wa(e.who)},{type:`signer.signed`,at:t,actor:`signer`,data:{docSha256:n,kind:r.kind,signatureSha256:r.sha256},personal:{name:r.typedName??e.signerName,...Wa(e.who)}},{type:`envelope.completed`,at:t,actor:`system`,data:{docSha256:n}}]}function Ja(e){let{at:t,docSha256:n,hasReason:r}=e;return[{type:`signer.declined`,at:t,actor:`signer`,data:{docSha256:n,hasReason:r,...Ga(e.order)},personal:Wa(e.who)},{type:`envelope.declined`,at:t,actor:`system`,data:{docSha256:n}}]}function Ya(e){let t=e.startsWith(``)?e.slice(1):e,n=[],r=[],i=``,a=!1,o=!1,s=1,c=1,l=()=>{r.push(i),i=``,o=!1},u=()=>{l(),(r.length>1||r[0]!==``||o)&&n.push({line:c,cells:r}),r=[],c=s};for(let e=0;e<t.length;e++){let n=t.charAt(e);a?n===`"`?t.charAt(e+1)===`"`?(i+=`"`,e++):a=!1:(n===`
38
38
  `&&s++,i+=n):n===`"`&&i===``?(a=!0,o=!0):n===`,`?l():n===`
39
39
  `||n===`\r`?(n===`\r`&&t.charAt(e+1)===`
40
- `&&e++,s++,u()):i+=n}return a?k({line:c,code:`UNTERMINATED_QUOTE`}):((i!==``||r.length>0)&&u(),O(n))}function Xa(e){let t=e.replace(/[\u0000-\u001f\u007f]/g,``),n=/^[=+\-@]/.test(t)?`'${t}`:t;return n.length>60?`${n.slice(0,60)}...`:n}const Za=/^signer\./,Qa=e=>/^participant\./.test(e)||/^signer\d+\./.test(e)||e.includes(`.`)&&!Za.test(e),$a=e=>e.filter(e=>!Za.test(e)&&!Qa(e)),eo=e=>k({issues:e.slice(0,50),total:e.length});function to(e,t){if(e.length>2e5)return eo([{line:0,code:`TOO_LARGE`}]);let n=Ya(e);if(!n.ok)return eo([n.error]);let[r,...i]=n.value;if(!r||i.length===0)return eo([{line:0,code:`EMPTY`}]);if(i.length>500)return eo([{line:0,code:`TOO_MANY_ROWS`}]);let a=t.filter(Qa);if(a.length>0)return eo(a.map(e=>({line:1,column:e,code:`TEMPLATE_UNSUPPORTED`})));let o=$a(t),s=r.cells.map(e=>e.trim()),c=[],l=new Set,u=new Map;s.forEach((e,t)=>{let n=e.toLowerCase(),r=n===`name`||n===`email`?n:e;if(l.has(r)){c.push({line:1,column:Xa(e),code:`DUPLICATE_COLUMN`});return}l.add(r),u.set(r,t),r!==`name`&&r!==`email`&&!o.includes(r)&&c.push({line:1,column:Xa(e),code:`UNKNOWN_COLUMN`})});for(let e of[`name`,`email`,...o])u.has(e)||c.push({line:1,column:e,code:`MISSING_COLUMN`});if(c.length>0)return eo(c);let d=[],f=[],p=new Map;for(let{line:e,cells:t}of i){if(t.length!==s.length){d.push({line:e,code:`BAD_ROW_WIDTH`});continue}let n=e=>t[u.get(e)],r=n(`name`),i=n(`email`),a={};for(let e of o)a[e]=n(e);let c=d.length,l=Kr({templateId:`t`,signer:{name:r,email:i}}),m=l.ok?[]:l.error.map(e=>e.path);m.includes(`signer.name`)&&d.push({line:e,column:`name`,code:`INVALID_NAME`}),m.includes(`signer.email`)&&d.push({line:e,column:`email`,code:`INVALID_EMAIL`,value:Xa(i)});for(let t of o){let n=a[t];n.trim()===``?d.push({line:e,column:t,code:`MISSING_FIELD`}):[...n].length>500&&d.push({line:e,column:t,code:`INVALID_FIELDS`})}if(d.length>c||!l.ok)continue;let h=l.value.signer.email,g=p.get(h);if(g!==void 0){d.push({line:e,column:`email`,code:`DUPLICATE_EMAIL`,other:g});continue}p.set(h,e),f.push({seq:f.length,line:e,name:l.value.signer.name,email:h,fields:a})}return d.length>0?eo(d):O(f)}const no={EMPTY:`the file needs a header line and at least one recipient.`,TOO_LARGE:`the file is too large.`,TOO_MANY_ROWS:`more than 500 recipients. Split the file.`,UNTERMINATED_QUOTE:`a quoted value is never closed.`,MISSING_COLUMN:`the header needs a column with this name.`,UNKNOWN_COLUMN:`the template has no placeholder with this name.`,DUPLICATE_COLUMN:`this column appears more than once.`,TEMPLATE_UNSUPPORTED:`bulk send fills one signer per envelope, so this placeholder cannot be filled. Use a template without it.`,BAD_ROW_WIDTH:`the row has a different number of values from the header.`,INVALID_NAME:`enter the recipient's name (up to 200 characters).`,INVALID_EMAIL:`is not a valid email address.`,INVALID_FIELDS:`this value is too long (500 characters at most).`,MISSING_FIELD:`the template needs a value here.`,DUPLICATE_EMAIL:`this address is already in the file.`};function ro(e){let t=e.line===0?`File`:`Line ${e.line}`,n=e.column?`, ${e.column}`:``;return e.code===`INVALID_EMAIL`?`${t}${n}: "${e.value??``}" ${no.INVALID_EMAIL}`:e.code===`DUPLICATE_EMAIL`?`${t}${n}: this address is already on line ${e.other}.`:`${t}${n}: ${no[e.code]}`}function io(e,t=10){let n=[];for(let r=0;r<e.length;r+=t)n.push(e.slice(r,r+t));return n}const ao=(e,t)=>`${e}:p${t}`,oo=e=>`${e}:t`,so=e=>`${e}:x`,co=(e,t)=>`${e}-${t}`,lo=(e,t)=>`bulk-${e}-${t}`,uo=/^bulk-([0-9a-f-]{36})-(\d{1,3})$/;function fo(e){let t=uo.exec(e);return t?{jobId:t[1],page:Number(t[2])}:null}const po=e=>`${e.sent} of ${e.total} sent${e.failed>0?`, ${e.failed} failed`:``}`,mo=10*6e4,ho=()=>crypto.getRandomValues(new Uint32Array(1))[0];function go(e=ho){for(;;){let t=e();if(t<4294e6)return String(t%10**6).padStart(6,`0`)}}function _o(e){if(typeof e!=`string`)return null;let t=e.trim();return/^[0-9]{6}$/.test(t)?t:null}const vo=(e,t,n)=>F(`esign-otp/1|${t}|${n}|${e}`);function yo(e,t){if(!e)return{ok:!0,sends:1,windowStart:t};let n=e.sentAt+3e4-t;return n>0?{ok:!1,code:`OTP_WAIT`,retryAfterSeconds:Math.ceil(n/1e3)}:t-e.windowStart>=36e5?{ok:!0,sends:1,windowStart:t}:e.sends>=5?{ok:!1,code:`RATE_LIMITED`}:{ok:!0,sends:e.sends+1,windowStart:e.windowStart}}async function bo(e,t,n,r){let i=D(crypto.getRandomValues(new Uint8Array(16)));return{hash:await vo(e,i,t),salt:i,expiresAt:n+mo,attempts:0,sentAt:n,sends:r.sends,windowStart:r.windowStart}}async function xo(e,t,n,r){if(!e||r>=e.expiresAt)return{ok:!1,code:`OTP_EXPIRED`};if(e.attempts>=5)return{ok:!1,code:`OTP_LOCKED`};if(me(await vo(t,e.salt,n),e.hash))return{ok:!0};let i={...e,attempts:e.attempts+1};return{ok:!1,code:`OTP_INVALID`,attemptsLeft:5-i.attempts,next:i}}function So(e,t,n){return n===void 0?e.otpDefault===!0?!0:e.otpContractTemplates!==!1&&!t.integrations:n}function Co(e,t,n){let r=So(e,t,n);return r||n!==void 0?{otp:r}:{}}const wo=e=>async(t,n,r)=>{let i=Co(n,r);if(!i.otp)return{};let a=n.licenceKey;return ce(await e.check({settings:{get:async()=>a},site:t.site}),`new`).ok?i:{}},To=e=>e.storage.bulk,Eo=(e,t)=>typeof e==`object`&&e?e[t]:void 0,Do=(e,t)=>({id:e,templateName:t.templateName,title:t.title,status:t.status,total:t.total,sent:t.sent,failed:t.failed,progress:po(t),createdAt:t.createdAt});async function Oo(e,t){let n=Eo(e.input,`templateId`),r=Eo(e.input,`csv`),i=Eo(e.input,`title`);if(typeof n!=`string`||n===``||n.length>200||n.includes(`:`))return H([{path:`templateId`,code:`INVALID_TEMPLATE_ID`}]);if(typeof r!=`string`)return H([{path:`csv`,code:`INVALID_INPUT`}]);let a=typeof i==`string`?i.trim():``;if(a.length>200)return H([{path:`title`,code:`INVALID_TITLE`}]);if(!L(t))return{ok:!1,error:{code:`SITE_URL_MISSING`,message:nr}};let[o,s]=await Promise.all([B(t).templates.getMany([n]),t.settings.list()]),c=qr(o.get(n),void 0,void 0);if(!c.ok)return U(`TEMPLATE_NOT_FOUND`);let l=to(r,c.value.fields);if(!l.ok){let{issues:e,total:t}=l.error;return{ok:!1,error:{code:`BULK_INVALID`,message:`${t} problem${t===1?``:`s`} in the file (up to 500 recipients). Nothing was sent.`},issues:e,total:t,messages:e.map(ro)}}let u=Object.fromEntries(s.map(e=>[e.key,e.value])),d=crypto.randomUUID(),f=N(),p=io(l.value),m=typeof u.senderName==`string`?u.senderName:void 0,h=typeof e.user?.id==`string`&&e.user.id?e.user.id:void 0,g={kind:`job`,templateId:n,templateVersion:c.value.version,templateName:c.value.name,title:a||c.value.name,status:`running`,total:l.value.length,sent:0,failed:0,pages:p.length,expiryDays:ha(u.expiryDays),otp:Co(u,c.value).otp===!0,...m?{senderName:m}:{},failures:[],createdAt:f,updatedAt:f,...h?{createdBy:h}:{}},_=[{id:d,data:g},{id:oo(d),data:{kind:`tpl`,template:c.value,createdAt:f}},...p.map((e,t)=>({id:ao(d,t),data:{kind:`page`,jobId:d,page:t,createdAt:f,rows:e.map(e=>({seq:e.seq,status:`pending`,name:e.name,email:e.email,fields:e.fields}))}}))];return await To(t).putMany(_),await t.cron?.schedule(lo(d,0),{schedule:f}),{ok:!0,job:Do(d,g)}}async function ko(e,t){let n=Eo(e.input,`id`);if(typeof n!=`string`||n===``||n.includes(`:`))return H([{path:`id`,code:`INVALID_INPUT`}]);let r=To(t),i=await r.get(n);if(!i||i.kind!==`job`)return U(`NOT_FOUND`);if(i.status!==`running`)return{ok:!0,job:Do(n,i)};let a=N(),o={...i,status:`cancelled`,updatedAt:a};return await r.putMany([{id:so(n),data:{kind:`flag`,createdAt:a}},{id:n,data:o}]),{ok:!0,job:Do(n,o)}}var Ao=class{constructor(e){this.name=e}},jo=class{constructor(e){this.bytes=e}},Mo=class{constructor(e,t){this.num=e,this.gen=t}},No=class extends Error{constructor(e,t){super(t),this.code=e}};const W=e=>new No(`PDF_MALFORMED`,e),Po=new Set([0,9,10,12,13,32]),Fo=new Set([40,41,60,62,91,93,123,125,47,37]),Io=e=>!Po.has(e)&&!Fo.has(e);function Lo(e){let t=``;for(let n=0;n<e.length;n+=32768)t+=String.fromCharCode.apply(null,e.subarray(n,n+32768));return t}const Ro=new Uint8Array(new Uint16Array([1]).buffer)[0]===1;function zo(e){if(!Ro)return Lo(e);let t=new Uint16Array(e.length);return t.set(e),new TextDecoder(`utf-16le`,{ignoreBOM:!0}).decode(t)}const Bo=e=>e instanceof Map,Vo=e=>e instanceof Ao?e.name:void 0;var Ho=class{pos;constructor(e,t=0){this.s=e,this.pos=t}code(e=this.pos){return this.s.charCodeAt(e)}skipSpace(){let{s:e}=this;for(;this.pos<e.length;){let t=this.code();if(Po.has(t))this.pos++;else if(t===37)for(;this.pos<e.length&&this.code()!==10&&this.code()!==13;)this.pos++;else break}}token(){this.skipSpace();let{s:e}=this;if(this.pos>=e.length)return null;let t=this.code();if(t===91||t===93)return this.pos++,t===91?{t:`open`,v:`[`}:{t:`close`,v:`]`};if(t===60&&this.code(this.pos+1)===60)return this.pos+=2,{t:`open`,v:`<<`};if(t===62&&this.code(this.pos+1)===62)return this.pos+=2,{t:`close`,v:`>>`};if(t===60)return{t:`val`,v:this.hexString()};if(t===40)return{t:`val`,v:this.literalString()};if(t===47)return{t:`val`,v:this.name()};let n=this.pos;for(;this.pos<e.length&&Io(this.code());)this.pos++;if(this.pos===n)throw W(`unexpected byte at ${n}`);let r=e.slice(n,this.pos);return/^[+-]?(\d+\.?\d*|\.\d+)$/.test(r)?{t:`num`,v:Number(r),int:/^[+-]?\d+$/.test(r)}:{t:`kw`,v:r}}name(){let e=++this.pos;for(;this.pos<this.s.length&&Io(this.code());)this.pos++;return new Ao(this.s.slice(e,this.pos).replace(/#([0-9A-Fa-f]{2})/g,(e,t)=>String.fromCharCode(parseInt(t,16))))}hexString(){let e=this.s.indexOf(`>`,this.pos);if(e<0)throw W(`unterminated hex string`);let t=this.s.slice(this.pos+1,e).replace(/[^0-9A-Fa-f]/g,``);this.pos=e+1,t.length%2&&(t+=`0`);let n=``;for(let e=0;e<t.length;e+=2)n+=String.fromCharCode(parseInt(t.slice(e,e+2),16));return new jo(n)}literalString(){let{s:e}=this,t=1,n=``;for(this.pos++;this.pos<e.length;){let r=e[this.pos++];if(r===`\\`){let t=e[this.pos++]??``,r={n:`
40
+ `&&e++,s++,u()):i+=n}return a?k({line:c,code:`UNTERMINATED_QUOTE`}):((i!==``||r.length>0)&&u(),O(n))}function Xa(e){let t=e.replace(/[\u0000-\u001f\u007f]/g,``),n=/^[=+\-@]/.test(t)?`'${t}`:t;return n.length>60?`${n.slice(0,60)}...`:n}const Za=/^signer\./,Qa=e=>/^participant\./.test(e)||/^signer\d+\./.test(e)||e.includes(`.`)&&!Za.test(e),$a=e=>e.filter(e=>!Za.test(e)&&!Qa(e)),eo=e=>k({issues:e.slice(0,50),total:e.length});function to(e,t){if(e.length>2e5)return eo([{line:0,code:`TOO_LARGE`}]);let n=Ya(e);if(!n.ok)return eo([n.error]);let[r,...i]=n.value;if(!r||i.length===0)return eo([{line:0,code:`EMPTY`}]);if(i.length>500)return eo([{line:0,code:`TOO_MANY_ROWS`}]);let a=t.filter(Qa);if(a.length>0)return eo(a.map(e=>({line:1,column:e,code:`TEMPLATE_UNSUPPORTED`})));let o=$a(t),s=r.cells.map(e=>e.trim()),c=[],l=new Set,u=new Map;s.forEach((e,t)=>{let n=e.toLowerCase(),r=n===`name`||n===`email`?n:e;if(l.has(r)){c.push({line:1,column:Xa(e),code:`DUPLICATE_COLUMN`});return}l.add(r),u.set(r,t),r!==`name`&&r!==`email`&&!o.includes(r)&&c.push({line:1,column:Xa(e),code:`UNKNOWN_COLUMN`})});for(let e of[`name`,`email`,...o])u.has(e)||c.push({line:1,column:e,code:`MISSING_COLUMN`});if(c.length>0)return eo(c);let d=[],f=[],p=new Map;for(let{line:e,cells:t}of i){if(t.length!==s.length){d.push({line:e,code:`BAD_ROW_WIDTH`});continue}let n=e=>t[u.get(e)],r=n(`name`),i=n(`email`),a={};for(let e of o)a[e]=n(e);let c=d.length,l=qr({templateId:`t`,signer:{name:r,email:i}}),m=l.ok?[]:l.error.map(e=>e.path);m.includes(`signer.name`)&&d.push({line:e,column:`name`,code:`INVALID_NAME`}),m.includes(`signer.email`)&&d.push({line:e,column:`email`,code:`INVALID_EMAIL`,value:Xa(i)});for(let t of o){let n=a[t];n.trim()===``?d.push({line:e,column:t,code:`MISSING_FIELD`}):[...n].length>500&&d.push({line:e,column:t,code:`INVALID_FIELDS`})}if(d.length>c||!l.ok)continue;let h=l.value.signer.email,g=p.get(h);if(g!==void 0){d.push({line:e,column:`email`,code:`DUPLICATE_EMAIL`,other:g});continue}p.set(h,e),f.push({seq:f.length,line:e,name:l.value.signer.name,email:h,fields:a})}return d.length>0?eo(d):O(f)}const no={EMPTY:`the file needs a header line and at least one recipient.`,TOO_LARGE:`the file is too large.`,TOO_MANY_ROWS:`more than 500 recipients. Split the file.`,UNTERMINATED_QUOTE:`a quoted value is never closed.`,MISSING_COLUMN:`the header needs a column with this name.`,UNKNOWN_COLUMN:`the template has no placeholder with this name.`,DUPLICATE_COLUMN:`this column appears more than once.`,TEMPLATE_UNSUPPORTED:`bulk send fills one signer per envelope, so this placeholder cannot be filled. Use a template without it.`,BAD_ROW_WIDTH:`the row has a different number of values from the header.`,INVALID_NAME:`enter the recipient's name (up to 200 characters).`,INVALID_EMAIL:`is not a valid email address.`,INVALID_FIELDS:`this value is too long (500 characters at most).`,MISSING_FIELD:`the template needs a value here.`,DUPLICATE_EMAIL:`this address is already in the file.`};function ro(e){let t=e.line===0?`File`:`Line ${e.line}`,n=e.column?`, ${e.column}`:``;return e.code===`INVALID_EMAIL`?`${t}${n}: "${e.value??``}" ${no.INVALID_EMAIL}`:e.code===`DUPLICATE_EMAIL`?`${t}${n}: this address is already on line ${e.other}.`:`${t}${n}: ${no[e.code]}`}function io(e,t=10){let n=[];for(let r=0;r<e.length;r+=t)n.push(e.slice(r,r+t));return n}const ao=(e,t)=>`${e}:p${t}`,oo=e=>`${e}:t`,so=e=>`${e}:x`,co=(e,t)=>`${e}-${t}`,lo=(e,t)=>`bulk-${e}-${t}`,uo=/^bulk-([0-9a-f-]{36})-(\d{1,3})$/;function fo(e){let t=uo.exec(e);return t?{jobId:t[1],page:Number(t[2])}:null}const po=e=>`${e.sent} of ${e.total} sent${e.failed>0?`, ${e.failed} failed`:``}`,mo=10*6e4,ho=()=>crypto.getRandomValues(new Uint32Array(1))[0];function go(e=ho){for(;;){let t=e();if(t<4294e6)return String(t%10**6).padStart(6,`0`)}}function _o(e){if(typeof e!=`string`)return null;let t=e.trim();return/^[0-9]{6}$/.test(t)?t:null}const vo=(e,t,n)=>F(`esign-otp/1|${t}|${n}|${e}`);function yo(e,t){if(!e)return{ok:!0,sends:1,windowStart:t};let n=e.sentAt+3e4-t;return n>0?{ok:!1,code:`OTP_WAIT`,retryAfterSeconds:Math.ceil(n/1e3)}:t-e.windowStart>=36e5?{ok:!0,sends:1,windowStart:t}:e.sends>=5?{ok:!1,code:`RATE_LIMITED`}:{ok:!0,sends:e.sends+1,windowStart:e.windowStart}}async function bo(e,t,n,r){let i=D(crypto.getRandomValues(new Uint8Array(16)));return{hash:await vo(e,i,t),salt:i,expiresAt:n+mo,attempts:0,sentAt:n,sends:r.sends,windowStart:r.windowStart}}async function xo(e,t,n,r){if(!e||r>=e.expiresAt)return{ok:!1,code:`OTP_EXPIRED`};if(e.attempts>=5)return{ok:!1,code:`OTP_LOCKED`};if(me(await vo(t,e.salt,n),e.hash))return{ok:!0};let i={...e,attempts:e.attempts+1};return{ok:!1,code:`OTP_INVALID`,attemptsLeft:5-i.attempts,next:i}}function So(e,t,n){return n===void 0?e.otpDefault===!0?!0:e.otpContractTemplates!==!1&&!t.integrations:n}function Co(e,t,n){let r=So(e,t,n);return r||n!==void 0?{otp:r}:{}}const wo=e=>async(t,n,r)=>{let i=Co(n,r);if(!i.otp)return{};let a=n.licenceKey;return ce(await e.check({settings:{get:async()=>a},site:t.site}),`new`).ok?i:{}},To=e=>e.storage.bulk,Eo=(e,t)=>typeof e==`object`&&e?e[t]:void 0,Do=(e,t)=>({id:e,templateName:t.templateName,title:t.title,status:t.status,total:t.total,sent:t.sent,failed:t.failed,progress:po(t),createdAt:t.createdAt});async function Oo(e,t){let n=Eo(e.input,`templateId`),r=Eo(e.input,`csv`),i=Eo(e.input,`title`);if(typeof n!=`string`||n===``||n.length>200||n.includes(`:`))return H([{path:`templateId`,code:`INVALID_TEMPLATE_ID`}]);if(typeof r!=`string`)return H([{path:`csv`,code:`INVALID_INPUT`}]);let a=typeof i==`string`?i.trim():``;if(a.length>200)return H([{path:`title`,code:`INVALID_TITLE`}]);if(!L(t))return{ok:!1,error:{code:`SITE_URL_MISSING`,message:nr}};let[o,s]=await Promise.all([B(t).templates.getMany([n]),t.settings.list()]),c=Jr(o.get(n),void 0,void 0);if(!c.ok)return U(`TEMPLATE_NOT_FOUND`);let l=to(r,c.value.fields);if(!l.ok){let{issues:e,total:t}=l.error;return{ok:!1,error:{code:`BULK_INVALID`,message:`${t} problem${t===1?``:`s`} in the file (up to 500 recipients). Nothing was sent.`},issues:e,total:t,messages:e.map(ro)}}let u=Object.fromEntries(s.map(e=>[e.key,e.value])),d=crypto.randomUUID(),f=N(),p=io(l.value),m=typeof u.senderName==`string`?u.senderName:void 0,h=typeof e.user?.id==`string`&&e.user.id?e.user.id:void 0,g={kind:`job`,templateId:n,templateVersion:c.value.version,templateName:c.value.name,title:a||c.value.name,status:`running`,total:l.value.length,sent:0,failed:0,pages:p.length,expiryDays:ha(u.expiryDays),otp:Co(u,c.value).otp===!0,...m?{senderName:m}:{},failures:[],createdAt:f,updatedAt:f,...h?{createdBy:h}:{}},_=[{id:d,data:g},{id:oo(d),data:{kind:`tpl`,template:c.value,createdAt:f}},...p.map((e,t)=>({id:ao(d,t),data:{kind:`page`,jobId:d,page:t,createdAt:f,rows:e.map(e=>({seq:e.seq,status:`pending`,name:e.name,email:e.email,fields:e.fields}))}}))];return await To(t).putMany(_),await t.cron?.schedule(lo(d,0),{schedule:f}),{ok:!0,job:Do(d,g)}}async function ko(e,t){let n=Eo(e.input,`id`);if(typeof n!=`string`||n===``||n.includes(`:`))return H([{path:`id`,code:`INVALID_INPUT`}]);let r=To(t),i=await r.get(n);if(!i||i.kind!==`job`)return U(`NOT_FOUND`);if(i.status!==`running`)return{ok:!0,job:Do(n,i)};let a=N(),o={...i,status:`cancelled`,updatedAt:a};return await r.putMany([{id:so(n),data:{kind:`flag`,createdAt:a}},{id:n,data:o}]),{ok:!0,job:Do(n,o)}}var Ao=class{constructor(e){this.name=e}},jo=class{constructor(e){this.bytes=e}},Mo=class{constructor(e,t){this.num=e,this.gen=t}},No=class extends Error{constructor(e,t){super(t),this.code=e}};const W=e=>new No(`PDF_MALFORMED`,e),Po=new Set([0,9,10,12,13,32]),Fo=new Set([40,41,60,62,91,93,123,125,47,37]),Io=e=>!Po.has(e)&&!Fo.has(e);function Lo(e){let t=``;for(let n=0;n<e.length;n+=32768)t+=String.fromCharCode.apply(null,e.subarray(n,n+32768));return t}const Ro=new Uint8Array(new Uint16Array([1]).buffer)[0]===1;function zo(e){if(!Ro)return Lo(e);let t=new Uint16Array(e.length);return t.set(e),new TextDecoder(`utf-16le`,{ignoreBOM:!0}).decode(t)}const Bo=e=>e instanceof Map,Vo=e=>e instanceof Ao?e.name:void 0;var Ho=class{pos;constructor(e,t=0){this.s=e,this.pos=t}code(e=this.pos){return this.s.charCodeAt(e)}skipSpace(){let{s:e}=this;for(;this.pos<e.length;){let t=this.code();if(Po.has(t))this.pos++;else if(t===37)for(;this.pos<e.length&&this.code()!==10&&this.code()!==13;)this.pos++;else break}}token(){this.skipSpace();let{s:e}=this;if(this.pos>=e.length)return null;let t=this.code();if(t===91||t===93)return this.pos++,t===91?{t:`open`,v:`[`}:{t:`close`,v:`]`};if(t===60&&this.code(this.pos+1)===60)return this.pos+=2,{t:`open`,v:`<<`};if(t===62&&this.code(this.pos+1)===62)return this.pos+=2,{t:`close`,v:`>>`};if(t===60)return{t:`val`,v:this.hexString()};if(t===40)return{t:`val`,v:this.literalString()};if(t===47)return{t:`val`,v:this.name()};let n=this.pos;for(;this.pos<e.length&&Io(this.code());)this.pos++;if(this.pos===n)throw W(`unexpected byte at ${n}`);let r=e.slice(n,this.pos);return/^[+-]?(\d+\.?\d*|\.\d+)$/.test(r)?{t:`num`,v:Number(r),int:/^[+-]?\d+$/.test(r)}:{t:`kw`,v:r}}name(){let e=++this.pos;for(;this.pos<this.s.length&&Io(this.code());)this.pos++;return new Ao(this.s.slice(e,this.pos).replace(/#([0-9A-Fa-f]{2})/g,(e,t)=>String.fromCharCode(parseInt(t,16))))}hexString(){let e=this.s.indexOf(`>`,this.pos);if(e<0)throw W(`unterminated hex string`);let t=this.s.slice(this.pos+1,e).replace(/[^0-9A-Fa-f]/g,``);this.pos=e+1,t.length%2&&(t+=`0`);let n=``;for(let e=0;e<t.length;e+=2)n+=String.fromCharCode(parseInt(t.slice(e,e+2),16));return new jo(n)}literalString(){let{s:e}=this,t=1,n=``;for(this.pos++;this.pos<e.length;){let r=e[this.pos++];if(r===`\\`){let t=e[this.pos++]??``,r={n:`
41
41
  `,r:`\r`,t:` `,b:`\b`,f:`\f`};if(t in r)n+=r[t];else if(t>=`0`&&t<=`7`){let r=t;for(;r.length<3&&(e[this.pos]??``)>=`0`&&(e[this.pos]??``)<=`7`;)r+=e[this.pos++];n+=String.fromCharCode(parseInt(r,8)&255)}else t===`\r`?e[this.pos]===`
42
42
  `&&this.pos++:t!==`
43
43
  `&&(n+=t)}else if(r===`(`)t++,n+=r;else if(r===`)`){if(--t===0)return new jo(n);n+=r}else n+=r}throw W(`unterminated string`)}value(e=0){if(e>64)throw W(`nesting too deep`);let t=this.token();if(!t)throw W(`unexpected end of file`);switch(t.t){case`val`:return t.v;case`num`:if(t.int&&t.v>=0){let e=this.pos,n=this.token();if(n?.t===`num`&&n.int){let e=this.token();if(e?.t===`kw`&&e.v===`R`)return new Mo(t.v,n.v)}this.pos=e}return t.v;case`kw`:if(t.v===`true`||t.v===`false`)return t.v===`true`;if(t.v===`null`)return null;throw W(`unexpected keyword ${t.v.slice(0,20)}`);case`open`:{if(t.v===`[`){let t=[];for(;;){if(this.skipSpace(),this.s[this.pos]===`]`)return this.pos++,t;t.push(this.value(e+1))}}let n=new Map;for(;;){if(this.skipSpace(),this.s.startsWith(`>>`,this.pos))return this.pos+=2,n;let t=this.value(e+1);if(!(t instanceof Ao))throw W(`dictionary key is not a name`);n.set(t.name,this.value(e+1))}}default:throw W(`unexpected delimiter`)}}keyword(e){let t=this.token();if(t?.t!==`kw`||t.v!==e)throw W(`expected ${e}`)}int(){let e=this.token();if(e?.t!==`num`||!e.int)throw W(`expected an integer`);return e.v}};const Uo=2e5;async function Wo(e,t){let n=new Blob([e]).stream().pipeThrough(new DecompressionStream(`deflate`)).getReader(),r=[],i=0;try{for(let e=await n.read();!e.done;e=await n.read()){if(i+=e.value.length,i>t)throw await n.cancel().catch(()=>void 0),new No(`PDF_UNSUPPORTED`,`a compressed stream inflates too large`);r.push(e.value)}}catch(e){throw e instanceof No?e:W(`a compressed stream does not inflate`)}let a=new Uint8Array(i),o=0;for(let e of r)a.set(e,o),o+=e.length;return a}function Go(e,t){let n=t+1,r=new Uint8Array(t),i=``;for(let a=0;a+n<=e.length;a+=n){let n=e.charCodeAt(a),o=new Uint8Array(t);for(let i=0;i<t;i++){let t=e.charCodeAt(a+1+i),s=i>0?o[i-1]:0,c=r[i],l=i>0?r[i-1]:0,u=0;if(n===1)u=s;else if(n===2)u=c;else if(n===3)u=s+c>>1;else if(n===4){let e=s+c-l,t=Math.abs(e-s),n=Math.abs(e-c),r=Math.abs(e-l);u=t<=n&&t<=r?s:n<=r?c:l}o[i]=t+u&255}for(let e of o)i+=String.fromCharCode(e);r=o}return i}var Ko=class e{s;entries=new Map;trailer=new Map;startxref=0;xrefKind=`table`;size=0;encrypted=!1;cache=new Map;objStreams=new Map;inflateBudget=16777216;constructor(e){this.bytes=e,this.s=zo(e)}static async open(t){let n=new e(t);return await n.readXref(),n}async readXref(){let{s:e}=this;if(!e.slice(0,1024).includes(`%PDF-`))throw W(`no %PDF- header`);let t=e.slice(Math.max(0,e.length-2048)),n=t.lastIndexOf(`startxref`);if(n<0)throw W(`no startxref`);this.startxref=new Ho(t,n+9).int();let r=new Set,i=this.startxref,a=!0;for(;i!==void 0;){if(r.has(i)||i<0||i>=e.length||r.size>64)throw W(`bad xref chain`);r.add(i);let t=await this.readSection(i,a);a&&=(this.trailer=t,!1),t.has(`Encrypt`)&&(this.encrypted=!0);let n=t.get(`Size`);typeof n==`number`&&(this.size=Math.max(this.size,n));let o=t.get(`Prev`);i=typeof o==`number`?o:void 0}for(let e of this.entries.keys())this.size=Math.max(this.size,e+1);if(this.size>Uo)throw W(`too many objects`)}add(e,t){this.entries.has(e)||this.entries.set(e,t)}async readSection(e,t){let n=new Ho(this.s,e);if(n.skipSpace(),this.s.startsWith(`xref`,n.pos)){for(t&&(this.xrefKind=`table`),n.pos+=4;n.skipSpace(),!this.s.startsWith(`trailer`,n.pos);){let e=n.int(),t=n.int();if(t<0||e+t>Uo)throw W(`bad xref subsection`);for(let r=0;r<t;r++){let t=n.int(),i=n.int(),a=n.token();if(a?.t!==`kw`||a.v!==`n`&&a.v!==`f`)throw W(`bad xref entry`);this.add(e+r,a.v===`n`?{type:1,offset:t,gen:i}:{type:0})}}n.keyword(`trailer`);let e=n.value();if(!Bo(e))throw W(`trailer is not a dictionary`);let r=e.get(`XRefStm`);return typeof r==`number`&&await this.readSection(r,!1),e}t&&(this.xrefKind=`stream`);let{stream:r}=this.objectAt(e);if(!r||Vo(r.dict.get(`Type`))!==`XRef`)throw W(`startxref points at no xref`);let i=await this.decode(r),a=r.dict.get(`W`);if(!Array.isArray(a)||a.length!==3||!a.every(e=>typeof e==`number`&&e>=0&&e<=8))throw W(`bad xref stream /W`);let[o,s,c]=a,l=r.dict.get(`Size`),u=r.dict.get(`Index`)??[0,l];if(!Array.isArray(u)||u.length%2||!u.every(e=>typeof e==`number`))throw W(`bad xref stream /Index`);let d=o+s+c,f=(e,t)=>{let n=0;for(let r=0;r<t;r++)n=n*256+i.charCodeAt(e+r);return n},p=0;for(let e=0;e<u.length;e+=2){let t=u[e],n=u[e+1];if(t+n>Uo)throw W(`bad xref stream range`);for(let e=0;e<n;e++,p+=d){if(p+d>i.length)throw W(`xref stream too short`);let n=o===0?1:f(p,o),r=f(p+o,s),a=f(p+o+s,c);this.add(t+e,n===1?{type:1,offset:r,gen:a}:n===2?{type:2,stream:r,index:a}:{type:0})}}return r.dict}objectAt(e,t){let n=new Ho(this.s,e),r=n.int();if(n.int(),n.keyword(`obj`),t!==void 0&&r!==t)throw W(`object ${t} is not at its offset`);let i=n.value();if(n.skipSpace(),Bo(i)&&this.s.startsWith(`stream`,n.pos)){let e=n.pos+6;this.s[e]===`\r`&&e++,this.s[e]===`
44
44
  `&&e++;let t=i.get(`Length`);t instanceof Mo&&(t=this.lengthOf(t));let a=typeof t==`number`&&t>=0?e+t:-1;if(a<0||a>this.s.length||!/^\s*endstream/.test(this.s.slice(a,a+32))){let t=this.s.indexOf(`endstream`,e);if(t<0)throw W(`unterminated stream`);for(a=t;a>e&&(this.s[a-1]===`
45
45
  `||this.s[a-1]===`\r`);)a--}return{num:r,value:i,stream:{dict:i,data:this.bytes.subarray(e,a)}}}return{num:r,value:i}}lengthOf(e){let t=this.entries.get(e.num);if(t?.type!==1)return;let{value:n}=this.objectAt(t.offset,e.num);return typeof n==`number`?n:void 0}async decode(e){let t=e.dict.get(`Filter`),n=Array.isArray(t)?t:t===void 0?[]:[t],r=e.data,i=e.dict.get(`DecodeParms`);for(let e of n){if(Vo(e)!==`FlateDecode`)throw new No(`PDF_UNSUPPORTED`,`a cross-reference or object stream uses an unsupported filter`);r=await Wo(r,this.inflateBudget),this.inflateBudget-=r.length}let a=Lo(r),o=Array.isArray(i)?i[0]:i,s=Bo(o)?o.get(`Predictor`):void 0;if(typeof s==`number`&&s>=10){let e=Bo(o)?o.get(`Columns`):void 0;if(typeof e==`number`&&e>1024)throw W(`predictor rows too wide`);a=Go(a,typeof e==`number`&&e>0?e:1)}else if(typeof s==`number`&&s>1)throw new No(`PDF_UNSUPPORTED`,`unsupported predictor`);return a}objStream(e){let t=this.objStreams.get(e);return t||(t=(async()=>{let t=this.entries.get(e);if(t?.type!==1)throw W(`object stream missing`);let{stream:n}=this.objectAt(t.offset,e);if(!n||Vo(n.dict.get(`Type`))!==`ObjStm`)throw W(`not an object stream`);let r=await this.decode(n),i=n.dict.get(`N`),a=n.dict.get(`First`);if(typeof i!=`number`||typeof a!=`number`)throw W(`bad object stream`);let o=new Ho(r),s=[];for(let e=0;e<i;e++)o.int(),s.push(a+o.int());return{offsets:s,body:r}})(),this.objStreams.set(e,t)),t}async objectStreamBodies(){let e=new Set;for(let t of this.entries.values())t.type===2&&e.add(t.stream);return Promise.all([...e].map(async e=>(await this.objStream(e)).body))}async get(e){if(this.cache.has(e.num))return this.cache.get(e.num);let t=this.entries.get(e.num),n=null;if(t?.type===1)n=this.objectAt(t.offset,e.num).value;else if(t?.type===2){let{offsets:e,body:r}=await this.objStream(t.stream),i=e[t.index];if(i===void 0)throw W(`object not in its object stream`);n=new Ho(r,i).value()}return this.cache.set(e.num,n),n}async resolve(e){return e instanceof Mo?this.get(e):e}streamOf(e){let t=this.entries.get(e.num);return t?.type===1?this.objectAt(t.offset,e.num).stream:void 0}genOf(e){let t=this.entries.get(e);return t?.type===1?t.gen:0}async pagesRef(){let e=await this.resolve(this.trailer.get(`Root`)),t=Bo(e)?e.get(`Pages`):void 0;if(!(t instanceof Mo))throw W(`no page tree`);return t}async pages(){let e=[],t=new Set,n=async(r,i,a)=>{if(t.has(r.num)||a>32)throw W(`page tree loops`);t.add(r.num);let o=await this.get(r);if(!Bo(o))throw W(`page tree node is not a dictionary`);let s=new Map(i);for(let e of[`Resources`,`MediaBox`,`CropBox`,`Rotate`])o.has(e)&&s.set(e,o.get(e));let c=await this.resolve(o.get(`Kids`));if(Vo(o.get(`Type`))===`Pages`||Array.isArray(c)&&Vo(o.get(`Type`))!==`Page`){if(!Array.isArray(c))throw W(`page tree node has no kids`);for(let e of c){if(!(e instanceof Mo))throw W(`page tree kid is not a reference`);await n(e,s,a+1)}return}if(e.length>=500)throw new No(`PDF_UNSUPPORTED`,`more than 500 pages`);let l=await this.box(s.get(`MediaBox`));if(!l)throw W(`a page has no MediaBox`);let u=await this.box(s.get(`CropBox`)),d=await this.resolve(s.get(`Rotate`)),f=((typeof d==`number`?Math.round(d/90)*90:0)%360+360)%360;e.push({ref:r,dict:o,resources:await this.resolve(s.get(`Resources`))??new Map,box:u??l,rotate:f})};if(await n(await this.pagesRef(),new Map,0),e.length===0)throw W(`no pages`);return e}async box(e){let t=await this.resolve(e);if(!Array.isArray(t)||t.length!==4)return;let n=[];for(let e of t){let t=await this.resolve(e);if(typeof t!=`number`)return;n.push(t)}let[r,i,a,o]=n,s=[Math.min(r,a),Math.min(i,o),Math.max(r,a),Math.max(i,o)];return s[2]-s[0]>0&&s[3]-s[1]>0?s:void 0}};function qo(e){let t=e.box[2]-e.box[0],n=e.box[3]-e.box[1];return e.rotate===90||e.rotate===270?{w:n,h:t}:{w:t,h:n}}const Jo=3*1024*1024,Yo=[`signature`,`name`,`date`,`text`],Xo={NOT_A_PDF:`That file is not a PDF.`,PDF_TOO_LARGE:`PDF templates can be at most ${Jo/(1024*1024)} MB.`,PDF_MALFORMED:`That PDF cannot be read. Open it and save or print it to a new PDF, then upload that.`,PDF_ENCRYPTED:`That PDF is password-protected or encrypted. Upload a copy without protection.`,PDF_ACTIVE_CONTENT:`That PDF contains scripts, launch actions or dynamic forms. Upload a flattened copy (print to PDF).`,PDF_UNSUPPORTED:`That PDF uses a feature that cannot be stamped (or has more than 500 pages). Save or print it to a new PDF.`,INVALID_FIELDS:`Check the fields: each needs a page, a box inside that page and a known kind.`,INVALID_NAME:`Give the template a name of 1 to 200 characters.`},Zo=/\/(?:JavaScript|JS|Launch|RichMedia|XFA|SubmitForm|ImportData)(?![^\s/[\]()<>{}%])/,Qo=/>>\s*stream(?:\r\n|\n|\r)/g;function $o(e){let t=[],n=0;Qo.lastIndex=0;for(let r=Qo.exec(e);r;r=Qo.exec(e)){if(r.index<n)continue;t.push(e.slice(n,r.index+2));let i=e.indexOf(`endstream`,Qo.lastIndex);if(i<0)return t.join(` `);n=i+9,Qo.lastIndex=n}return t.push(e.slice(n)),t.join(` `)}const es=e=>e.includes(`#`)?e.replace(/#([0-9A-Fa-f]{2})/g,(e,t)=>String.fromCharCode(Number.parseInt(t,16))):e;async function ts(e){if(e.length>Jo)return k(`PDF_TOO_LARGE`);let t=``;for(let n=0;n<Math.min(e.length,1024);n++)t+=String.fromCharCode(e[n]);if(!t.includes(`%PDF-`))return k(`NOT_A_PDF`);try{let t=await Ko.open(e);return t.encrypted?k(`PDF_ENCRYPTED`):[$o(t.s),...await t.objectStreamBodies()].some(e=>Zo.test(es(e)))?k(`PDF_ACTIVE_CONTENT`):O({pages:(await t.pages()).map(e=>ns(qo(e)))})}catch(e){return e instanceof No?k(e.code):k(`PDF_MALFORMED`)}}const ns=({w:e,h:t})=>({w:Math.round(e*100)/100,h:Math.round(t*100)/100}),rs=/^[A-Za-z0-9_]{1,64}$/,is=/[\u0000-\u001F\u007F]/,as=e=>typeof e==`number`&&Number.isFinite(e);function os(e){if(e===void 0)return[];if(!Array.isArray(e)||e.length>16)return null;let t=[];for(let n of e){if(typeof n!=`object`||!n)return null;let{key:e,label:r,required:i}=n,a=typeof r==`string`?r.trim():``;if(typeof e!=`string`||!rs.test(e)||t.some(t=>t.key===e)||!a||[...a].length>100||is.test(a)||i!==void 0&&typeof i!=`boolean`)return null;t.push({key:e,label:a,...i?{required:!0}:{}})}return t}function ss(e,t,n){if(e===void 0)return O([]);if(!Array.isArray(e)||e.length>50)return k([{path:`fields`,code:`INVALID_FIELDS`}]);let r=[],i=[];return e.forEach((e,a)=>{let o=typeof e==`object`&&e?e:{},s=t[(typeof o.page==`number`?o.page:0)-1],c=o.kind,l=o.signer??1;if(!(Yo.includes(c)&&Number.isInteger(o.page)&&s!==void 0&&as(o.x)&&as(o.y)&&as(o.w)&&as(o.h)&&o.x>=0&&o.y>=0&&o.w>=4&&o.h>=4&&o.x+o.w<=s.w+.5&&o.y+o.h<=s.h+.5&&Number.isInteger(l)&&l>=1&&l<=10&&(c===`text`?typeof o.key==`string`&&n.some(e=>e.key===o.key):o.key===void 0))){r.push({path:`fields.${a}`,code:`INVALID_FIELDS`});return}i.push({kind:c,page:o.page,x:o.x,y:o.y,w:o.w,h:o.h,...c===`text`?{key:o.key}:{},...l===1?{}:{signer:l}})}),r.length>0?k(r):O(i)}function cs(e){let t=[],n=[];return e.split(/\r?\n/).forEach((e,r)=>{let i=e.replace(/#.*/,``).trim().split(/\s+/).filter(Boolean);if(i.length===0)return;let[a,...o]=i,s=o.slice(0,5).map(Number),c=o.slice(5),l=c.find(e=>e.startsWith(`signer=`)),u=c.find(e=>!e.startsWith(`signer=`));if(s.length<5||s.some(e=>!Number.isFinite(e))||c.length>2){n.push(r+1);return}let[d,f,p,m,h]=s;t.push({kind:a,page:d,x:f,y:p,w:m,h,...u?{key:u}:{},...l?{signer:Number(l.slice(7))}:{}})}),n.length>0?k(n):O(t)}const ls=e=>e.map(e=>[e.kind,e.page,e.x,e.y,e.w,e.h,...e.key?[e.key]:[],...e.signer?[`signer=${e.signer}`]:[]].join(` `)).join(`
46
- `);function us(e,t){let n=new Map;for(let r of e){let e=t[(r.signer??1)-1];if(!e)continue;let i={x:r.x,y:r.y,w:r.w,h:r.h},a=e.signature,o=r.kind===`name`?e.name:r.kind===`date`?(e.signedAt??``).slice(0,10):r.kind===`text`?e.fieldValues?.[r.key??``]??``:a?.typedName??e.name,s=r.kind===`signature`&&a?.kind===`drawn`&&Array.isArray(a.strokes)?{kind:`strokes`,strokes:a.strokes,box:i}:{kind:`text`,text:o,font:r.kind===`signature`?`italic`:`regular`,box:i},c=n.get(r.page-1)??[];c.push(s),n.set(r.page-1,c)}return n}function ds(e,t){let n=Ui({...e,snapshot:``}),[r,...i]=n.blocks.map(e=>{if(e.type===`paragraph`&&e.text===Ii)return{...e,text:`This certificate records how the PDF document before it was signed. It was signed with a simple electronic signature: the signer consented to sign electronically, confirmed their intent to sign, and signed the exact PDF file identified by the document SHA-256 below. That file is the first bytes of this PDF, unchanged (see Original PDF below); the entries on its pages and these pages were added after it as an incremental update. Every step is recorded in a hash-chained audit trail; the final hash binds the document to the end of that trail. Anyone holding this PDF can check these values on the verify page.`};if(e.type===`table`&&e.rows.some(e=>e[0]===`Document SHA-256`)){let n=e.rows.flatMap(e=>e[0]===`Document SHA-256`?[e,[`Original PDF`,`The first ${t.bytes} bytes of this file (${t.pages} pages)`]]:[e]);return{...e,rows:n}}return e});return{...n,blocks:[...r?[r]:[],{type:`paragraph`,text:`Signatures and details for the ${t.pages}-page PDF document before this page.`},...i]}}const fs=e=>e.storage;function ps(e){let t=e.toBase64;if(typeof t==`function`)return t.call(e);let n=``;for(let t=0;t<e.length;t+=32768)n+=String.fromCharCode.apply(null,e.subarray(t,t+32768));return btoa(n)}function ms(e){try{let t=Uint8Array.fromBase64;if(typeof t==`function`)return t(e);let n=atob(e),r=new Uint8Array(n.length);for(let e=0;e<n.length;e++)r[e]=n.charCodeAt(e);return r}catch{return null}}function hs(e){let t=e[0];if(!t||e.length!==t.count)return null;let n=new Uint8Array(t.bytes),r=0;for(let[i,a]of e.entries()){if(!a||a.index!==i||a.sha256!==t.sha256||a.bytes!==t.bytes)return null;let e=ms(a.data);if(!e||r+e.length>n.length)return null;n.set(e,r),r+=e.length}return r===n.length?n:null}const gs=(e,t)=>`${e}:${t}`;function _s(e,t){let n=Math.max(1,Math.ceil(e.length/Pi));return Array.from({length:n},(r,i)=>({id:gs(t,i),data:{kind:`pdf-template`,contentType:`application/pdf`,index:i,count:n,bytes:e.length,sha256:t,data:ps(e.subarray(i*Pi,(i+1)*Pi))}}))}function vs(e,t,n,r,i){let a=Math.max(1,Math.ceil(t.length/Pi)),o=Math.floor(i/Pi);return Array.from({length:a},(i,s)=>({id:Ji(e,n,s),data:{envelopeId:e,kind:Fi,contentType:`application/pdf`,index:s,count:a,bytes:t.length,sha256:n,data:s<o&&r[s]?r[s].data:ps(t.subarray(s*Pi,(s+1)*Pi))}}))}const ys=e=>typeof e==`object`&&e&&!Array.isArray(e)?e:{},bs=/^[A-Za-z0-9_-]{1,100}$/,xs=(e,t)=>({ok:!1,error:{code:e,message:Xo[e]},...t?{issues:t}:{}}),Ss=e=>typeof e.user?.id==`string`&&e.user.id?e.user.id:void 0,Cs=e=>/limit|exceed/i.test(e instanceof Error?e.message:String(e)),ws=(e,t)=>({id:e,...t,pdf:{...t.pdf,ids:void 0}});async function Ts(e,t){let n=ys(e.input),r=typeof n.mediaId==`string`?n.mediaId.trim():``;if(!r||r.length>200)return H([{path:`mediaId`,code:`INVALID_INPUT`}]);let i=os(n.signerFields);if(i===null)return xs(`INVALID_FIELDS`,[{path:`signerFields`,code:`INVALID_FIELDS`}]);if(!t.media?.readBytes)return U(`NOT_FOUND`);let a=await t.media.get(r);if(!a)return U(`NOT_FOUND`);if(a.mimeType!==`application/pdf`&&!/\.pdf$/i.test(a.filename))return xs(`NOT_A_PDF`);if(typeof a.size==`number`&&a.size>Jo)return xs(`PDF_TOO_LARGE`);let o;try{o=await t.media.readBytes(r,{maxBytes:Jo})}catch(e){return Cs(e)?xs(`PDF_TOO_LARGE`):U(`NOT_FOUND`)}let s=await ts(o.bytes);if(!s.ok)return xs(s.error);let c=s.value.pages,l=ss(n.fields,c,i);if(!l.ok)return xs(`INVALID_FIELDS`,l.error);let u=(Hr(o.filename)??`document.pdf`).slice(0,120),d=n.name===void 0?u.replace(/\.pdf$/i,``)||u:Hr(n.name);if(!d)return xs(`INVALID_NAME`,[{path:`name`,code:`INVALID_NAME`}]);let f=await F(o.bytes),p=_s(o.bytes,f);await fs(t).pdf_files.putMany(p);let m=N(),h=`pdf_${crypto.randomUUID().replace(/-/g,``)}`,g={name:d,status:`active`,version:1,pdf:{sha256:f,bytes:o.bytes.length,filename:u,pages:c,ids:p.map(e=>e.id)},fields:l.value,signerFields:i,createdAt:m,updatedAt:m};return await fs(t).pdf_templates.put(h,g),{ok:!0,template:ws(h,g)}}async function Es(e,t){let n=ys(e.input),r=typeof n.id==`string`&&bs.test(n.id)?n.id:null;if(!r)return H([{path:`id`,code:`INVALID_INPUT`}]);let i=fs(t).pdf_templates,a=await i.get(r);if(!a||a.status!==`active`)return U(`TEMPLATE_NOT_FOUND`);let o=n.signerFields===void 0?a.signerFields:os(n.signerFields);if(o===null)return xs(`INVALID_FIELDS`,[{path:`signerFields`,code:`INVALID_FIELDS`}]);let s=ss(n.fields??a.fields,a.pdf.pages,o);if(!s.ok)return xs(`INVALID_FIELDS`,s.error);let c=n.name===void 0?a.name:Hr(n.name);if(!c)return xs(`INVALID_NAME`,[{path:`name`,code:`INVALID_NAME`}]);let l={...a,name:c,fields:s.value,signerFields:o,status:n.archived===!0?`archived`:`active`,version:a.version+1,updatedAt:N()};return await i.put(r,l),{ok:!0,template:ws(r,l)}}async function Ds(e,t){let n=ys(e.input),r=typeof n.templateId==`string`&&bs.test(n.templateId)?n.templateId:null,i=Kr({templateId:`pdf`,title:n.title,signer:n.signer});if(!r)return H([{path:`templateId`,code:`INVALID_TEMPLATE_ID`}]);if(!i.ok)return H(i.error);if(n.otp!==void 0&&typeof n.otp!=`boolean`)return H([{path:`otp`,code:`INVALID_INPUT`}]);let{envelopes:a,signers:o,audit_events:s}=B(t),[c,l]=await Promise.all([fs(t).pdf_templates.get(r),t.settings.list()]);if(!c||c.status!==`active`)return U(`TEMPLATE_NOT_FOUND`);let u=Object.fromEntries(l.map(e=>[e.key,e.value])),d=crypto.randomUUID(),f=N(),p=cr(),m=zr(d,1),{signer:h,title:g}=i.value,_={kind:`pdf`,name:c.pdf.filename,bytes:c.pdf.bytes,pages:c.pdf.pages.length,templateId:r,ids:c.pdf.ids,sizes:c.pdf.pages,fields:c.fields},v={title:g??c.name,templateId:r,templateVersion:c.version,status:`sent`,routing:`parallel`,delivery:`email`,signer:h,signerEmail:h.email.toLowerCase(),fieldValues:{},...c.signerFields.length>0?{signerFields:c.signerFields}:{},signerIds:[m],docSha256:c.pdf.sha256,snapshot:null,document:_,expiresAt:N(Date.parse(f)+ha(u.expiryDays)*864e5),sentAt:f,completedAt:null,finalHash:null,piiSalt:p,createdAt:f,updatedAt:f,...Co(u,{integrations:!1},n.otp)},y=await va(o,{id:m,data:{envelopeId:d,order:1,role:`signer`,name:h.name,email:h.email,as:`self`,status:`pending`,tokenHash:``,createdAt:f}},A());await a.put(d,v);let b=Ss(e),x=ci(v,`admin`,b);await s.putMany(await mr(d,[{...x,data:{...x.data,document:`pdf`,pdfBytes:c.pdf.bytes}},li(v,`admin`,b)],p));let S=await rr(t,{signerId:m,envelope:v,token:y,senderSetting:u.senderName,now:Date.parse(f)}),{piiSalt:C,...ee}=v;return{ok:!0,envelope:{id:d,...ee},...S?{}:{invitation:`SITE_URL_MISSING`}}}const Os=e=>typeof e==`object`&&!!e&&!Array.isArray(e);function ks(e){if(!Os(e))return k([{path:``,code:`INVALID_INPUT`}]);let t=e.signers,n=[];(!Array.isArray(t)||t.length<2||t.length>10)&&n.push({path:`signers`,code:`INVALID_SIGNERS`}),e.routing!==`parallel`&&e.routing!==`sequential`&&n.push({path:`routing`,code:`INVALID_INPUT`}),e.otp!==void 0&&typeof e.otp!=`boolean`&&n.push({path:`otp`,code:`INVALID_INPUT`});let r=[],i;for(let[a,o]of(Array.isArray(t)&&n.length===0?t:[]).entries()){let t=Kr({...e,signer:o});if(!t.ok){for(let e of t.error)e.path.startsWith(`signer.`)?n.push({...e,path:`signers.${a}.${e.path.slice(7)}`}):a===0&&n.push(e);continue}r.some(e=>e.email===t.value.signer.email)&&n.push({path:`signers.${a}.email`,code:`INVALID_SIGNER_EMAIL`}),r.push(t.value.signer),i??=t.value}return n.length>0||!i?k(n.length>0?n:[{path:``,code:`INVALID_INPUT`}]):O({draft:i,signers:r,routing:e.routing,...typeof e.otp==`boolean`?{otp:e.otp}:{}})}function As(e){return Object.fromEntries(e.flatMap((e,t)=>[[`signer${t+1}.name`,e.name],[`signer${t+1}.email`,e.email]]))}function js(e){return typeof e==`string`?e.slice(0,4e3).split(`
47
- `).map(e=>e.trim()).filter(e=>e!==``).map(e=>{let t=/^(.*?)\s*<([^<>]*)>$/.exec(e);if(t)return{name:t[1].trim(),email:t[2].trim()};let n=e.lastIndexOf(`,`);return n>0?{name:e.slice(0,n).trim(),email:e.slice(n+1).trim()}:{name:e,email:``}}):[]}const Ms=(e,t)=>e===`parallel`||t===1,Ns=e=>`waiting:${e}`;function Ps(e,t,n){return e!==`sequential`||n.every(e=>e.order>=t.order||e.status===`signed`)}function Fs(e,t){return{type:`signer.invited`,at:t,actor:`system`,data:{signer:e.order},personal:{name:e.name,email:e.email}}}function Is(e,t,n){return{type:`reminder.sent`,at:t,actor:`system`,data:{signer:e.order,reminder:n},personal:{email:e.email}}}function Ls(e,t){let[n,r]=qa({at:t.signedAt??``,docSha256:e.docSha256??``,consentVersion:t.consentVersion??``,consentSha256:t.consentSha256??``,signature:t.signature??{kind:`typed`,sha256:``},signerName:t.name,who:{...t.ip?{ip:t.ip}:{},...t.ua?{ua:t.ua}:{}}});return[n,r].map(e=>({...e,data:{...e?.data,signer:t.order}}))}const Rs=[`sent`,`in_progress`];function zs(e,t,n,r){let i=(e,t)=>n.some(n=>n.type===e&&n.data.signer===t),a=t.filter(e=>e.data.status===`signed`&&!i(`signer.signed`,e.data.order)).flatMap(t=>Ls(e,t.data)),o=Rs.includes(e.status),s=o&&t.every(e=>e.data.status===`signed`);if(s)return a.push({type:`envelope.completed`,at:r,actor:`system`,data:{docSha256:e.docSha256}}),{inputs:a,complete:s};let c=t.find(e=>e.data.status!==`signed`);return o&&e.routing===`sequential`&&c?.data.waiting&&c.data.status===`pending`?(i(`signer.invited`,c.data.order)||a.push(Fs(c.data,r)),{inputs:a,complete:s,invite:c.id}):{inputs:a,complete:s}}function Bs(e){return Number.isSafeInteger(e)&&e>=1&&e<=30?e:3}function Vs(e,t,n){if(!Rs.includes(e.status)||t.status!==`pending`||t.waiting||(t.reminders??0)>=5||e.expiresAt!==null&&Date.parse(e.expiresAt)<=n.now)return!1;let r=Date.parse(t.remindedAt??t.invitedAt??e.sentAt??``);return Number.isFinite(r)&&r+n.cadenceDays*864e5<=n.now}function Hs(e){let t=Qn(e),n=`This reminder's link replaces the one in the earlier email.`;return{to:t.to,subject:`Reminder: ${t.subject}`,text:`${t.text}\n${n}\n`,html:`${t.html??``}\n<p>${n}</p>`}}const Us=e=>`invite-${e}`;function Ws(e,t){return{message:e,status:`pending`,attempts:0,nextAttemptAt:t,createdAt:t}}const Gs=(e,{piiSalt:t,...n})=>({id:e,...n});async function Ks(e,t){let n=ks(e.input);if(!n.ok)return H(n.error);let r=L(t);if(!r)return{ok:!1,error:{code:`SITE_URL_MISSING`,message:nr}};let{draft:i,signers:a,routing:o,otp:s}=n.value,{templates:c,envelopes:l,snapshots:u,signers:d,audit_events:f}=B(t),{templateId:p,templateVersion:m}=i,h=m===void 0?void 0:z(p,m),[g,_]=await Promise.all([c.getMany(h?[p,h]:[p]),t.settings.list()]),v=qr(g.get(p),h?g.get(h):void 0,m);if(!v.ok)return U(`TEMPLATE_NOT_FOUND`);let y=e=>_.find(t=>t.key===e)?.value,b=N(),x=cr(),S=Zr({...i,fieldValues:{...i.fieldValues,...As(a)}},v.value,{now:b,piiSalt:x});if(!S.ok)return H(S.error);let C=crypto.randomUUID(),ee=await ii(C,{...S.value,routing:o},v.value,{now:b,tokenHash:``,expiryDays:ha(y(`expiryDays`))});if(!ee.ok)return Array.isArray(ee.error)?H(ee.error):U(`ENVELOPE_CLOSED`);let w={...ee.value.envelope,signerIds:a.map((e,t)=>zr(C,t+1)),...Co(Object.fromEntries(_.map(e=>[e.key,e.value])),v.value,s)};await u.putMany(ee.value.chunks);let T=new Map,E=[];for(let e=1;;e++){T=new Map,E=await Promise.all(a.map(async(e,t)=>{let n=w.signerIds[t],r=Ms(o,t+1)?A():void 0;return r&&T.set(n,r),{id:n,data:{envelopeId:C,order:t+1,role:`signer`,name:e.name,email:e.email,as:e.as,status:`pending`,tokenHash:r?await j(r):Ns(n),createdAt:b,...r?{invitedAt:b}:{waiting:!0}}}}));try{await d.putMany(E);break}catch(t){if(!ga(t)||e>=3)throw t}}await l.put(C,w);let D=typeof e.user?.id==`string`&&e.user.id?e.user.id:void 0,te=ci(w,`admin`,D),O=E.filter(e=>T.has(e.id));await f.putMany(await mr(C,[{...te,data:{...te.data,routing:o,signers:a.length}},li(w,`admin`,D),...O.map(e=>Fs(e.data,b))],x));let k=tr(t,y(`senderName`)),ne=Date.parse(b);return await I(t).putMany(O.map(e=>({id:Us(e.id),data:Ws(Qn({to:e.data.email,signerName:e.data.name,title:w.title,sender:k,link:`${r}/sign/${T.get(e.id)}`,expiresAt:w.expiresAt}),ne)}))),{ok:!0,envelope:Gs(C,w),signers:E.map(e=>({id:e.id,order:e.data.order,name:e.data.name,email:e.data.email,status:e.data.status}))}}const qs=1e3,Js=e=>e?.status===`active`&&e.public===!0;function Ys(e){let t=e.selfServeDailyCap;return typeof t==`number`&&Number.isInteger(t)&&t>=1&&t<=qs?t:50}function Xs(e){if(e!==void 0)return typeof e==`number`&&Number.isInteger(e)&&e>=1&&e<=qs?e:null}const Zs=e=>e.fields.filter(e=>!e.startsWith(`signer.`)&&!e.startsWith(`participant.`)),Qs=(e,t)=>`rl:ss-cap:${e}:${new Date(t).toISOString().slice(0,10)}`,$s=(e,t)=>`${e}:${(Math.floor(t/864e5)+1)*86400}`,ec=(e,t)=>{let n=new Set(Zs(t));return Object.keys(e).filter(e=>!n.has(e))},tc=`self-serve-`,nc=(e,t)=>({ok:!1,error:{code:e,message:t}}),rc=()=>nc(`TURNSTILE_NOT_CONFIGURED`,`Self-serve forms need the Turnstile site and secret keys in the settings.`),ic=(e,t)=>typeof e==`object`&&e?e[t]:void 0;async function ac(e,t,n){return!(await Sn({get:t=>e.kv.get(t),set:(t,n)=>e.kv.set(t,n)},t,n,{scope:`self-serve`,limit:5,windowSeconds:600,salt:`esign-self-serve/1`})).ok}const oc=e=>typeof e==`string`?e.trim():``;async function sc(e,t,n){let r=n.get(`licenceKey`),i=ce(await e.check({settings:{get:async()=>r??null},site:t.site}),`new`);return i.ok?null:oe(i.error).body}async function cc(e,t,n,r){let[i,a]=await Promise.all([B(e).templates.get(t),n]),o=await sc(r,e,a);if(o)return o;let s=a.get(`turnstileSiteKey`);return Js(i)?oc(s)?{ok:!0,template:{id:t,name:i.name,...i.description?{description:i.description}:{},fields:Zs(i)},turnstileSiteKey:oc(s)}:rc():U(`TEMPLATE_NOT_FOUND`)}const lc=async e=>new Map((await e.settings.list()).map(e=>[e.key,e.value])),uc=e=>async(t,n)=>{let r=oc(ic(t.input,`templateId`));if(!r||r.includes(`:`))return H([{path:`templateId`,code:`INVALID_TEMPLATE_ID`}]);if(ic(t.input,`describe`)===!0)return cc(n,r,lc(n),e);if(oc(ic(t.input,`website`))!==``)return{ok:!0,status:`check_email`};let i=Kr({templateId:r,signer:{name:ic(t.input,`name`),email:ic(t.input,`email`)},fields:ic(t.input,`fields`)});if(!i.ok)return H(i.error);if(!L(n))return nc(`SITE_URL_MISSING`,`The site URL is not set, so the signing link cannot be emailed.`);let a=await lc(n),o=await sc(e,n,a);if(o)return o;let s=Date.now();if(await ac(n,t.requestMeta?.ip??`unknown`,s))return U(`RATE_LIMITED`);let c=a.get(`turnstileSecretKey`),l=a.get(`turnstileSiteKey`);if(!oc(c)||!oc(l))return rc();if(!(await zn((e,t)=>{if(!n.http)throw Error(`network:request is not granted`);return n.http.fetch(e,t)},{secret:oc(c),token:oc(ic(t.input,`turnstileToken`)),...t.requestMeta?.ip?{remoteIp:t.requestMeta.ip}:{}})).ok)return U(`TURNSTILE_FAILED`);let{templates:u,envelopes:d}=B(n),f=await u.get(r);if(!Js(f))return U(`TEMPLATE_NOT_FOUND`);let p=ec(i.value.fieldValues,f);if(p.length>0)return H(p.map(e=>({path:`fields.${e}`,code:`INVALID_FIELDS`})));let m=N(s),h=Zr(i.value,f,{now:m,piiSalt:cr()});if(!h.ok)return H(h.error);let g=Qs(r,s),_=Number.parseInt(await n.kv.get(g)??`0`,10);if((Number.isFinite(_)?_:0)>=Ys(f))return nc(`SELF_SERVE_FULL`,`This form has reached its limit for today.`);await n.kv.set(g,$s((Number.isFinite(_)?_:0)+1,s));let v=crypto.randomUUID();return await d.put(v,{...h.value,selfServe:!0}),await n.cron?.schedule(`${tc}${v}`,{schedule:m,data:{envelopeId:v}}),{ok:!0,status:`check_email`}};async function dc(e,t){let n=oc(ic(e.input,`id`)),r=ic(e.input,`enabled`),i=Xs(ic(e.input,`dailyCap`));if(!n||n.includes(`:`)||typeof r!=`boolean`||i===null)return H([{path:i===null?`dailyCap`:`enabled`,code:`INVALID_INPUT`}]);let{templates:a}=B(t),o=await a.get(n);if(!o||o.status!==`active`)return U(`TEMPLATE_NOT_FOUND`);let s={...o,public:r,...i===void 0?{}:{selfServeDailyCap:i},updatedAt:N()};return await a.put(n,s),{ok:!0,template:{id:n,public:r,selfServeDailyCap:s.selfServeDailyCap??50}}}const G=e=>({blocks:e}),K=(e,t=200)=>typeof e==`string`?e.trim().slice(0,t):``,q=(e,t,n)=>({severity:e,title:t,...n?{message:n}:{}}),fc=(e,t)=>_(e,t,{style:`secondary`});async function pc(e){let{items:t}=await B(e).templates.query({where:{status:`active`},limit:100});return t.sort((e,t)=>e.data.name.localeCompare(t.data.name))}const mc={running:`Running`,done:`Done`,cancelled:`Cancelled`},hc=()=>fc(`bulk.back`,`Back to bulk send`);async function gc(e,t=[],n={}){let[r,o]=await Promise.all([pc(e.ctx),To(e.ctx).query({where:{kind:`job`},orderBy:{createdAt:`desc`},limit:10})]),s=o.items.map(({id:e,data:t})=>{let n=t;return{template:n.templateName,title:n.title,status:mc[n.status],progress:po(n),created:n.createdAt,open:_(`bulk.open`,`Open`,{value:e})}});return G([i(`Bulk send`),...h([!L(e.ctx)&&q(`warning`,`Set the site URL`,nr)]),...t,a(`Send one template to many people, each in their own envelope. Paste a CSV: the first line is the header (name, email, then one column per placeholder of the template), then one line per recipient, up to 500. Every row is checked first; if any is wrong nothing is sent. Envelopes go out 10 at a time.`),w({fields:[x(`templateId`,`Template`,r.map(({id:e,data:t})=>({label:`${t.name} (columns: name, email${$a(t.fields).map(e=>`, ${e}`).join(``)})`,value:e})),n.templateId?{initialValue:n.templateId}:{}),y(`title`,`Envelope title (optional)`,n.title?{initialValue:n.title}:{}),y(`csv`,`Recipients (CSV)`,{multiline:!0,placeholder:`name,email
46
+ `);function us(e,t){let n=new Map;for(let r of e){let e=t[(r.signer??1)-1];if(!e)continue;let i={x:r.x,y:r.y,w:r.w,h:r.h},a=e.signature,o=r.kind===`name`?e.name:r.kind===`date`?(e.signedAt??``).slice(0,10):r.kind===`text`?e.fieldValues?.[r.key??``]??``:a?.typedName??e.name,s=r.kind===`signature`&&a?.kind===`drawn`&&Array.isArray(a.strokes)?{kind:`strokes`,strokes:a.strokes,box:i}:{kind:`text`,text:o,font:r.kind===`signature`?`italic`:`regular`,box:i},c=n.get(r.page-1)??[];c.push(s),n.set(r.page-1,c)}return n}function ds(e,t){let n=Ui({...e,snapshot:``}),[r,...i]=n.blocks.map(e=>{if(e.type===`paragraph`&&e.text===Ii)return{...e,text:`This certificate records how the PDF document before it was signed. It was signed with a simple electronic signature: the signer consented to sign electronically, confirmed their intent to sign, and signed the exact PDF file identified by the document SHA-256 below. That file is the first bytes of this PDF, unchanged (see Original PDF below); the entries on its pages and these pages were added after it as an incremental update. Every step is recorded in a hash-chained audit trail; the final hash binds the document to the end of that trail. Anyone holding this PDF can check these values on the verify page.`};if(e.type===`table`&&e.rows.some(e=>e[0]===`Document SHA-256`)){let n=e.rows.flatMap(e=>e[0]===`Document SHA-256`?[e,[`Original PDF`,`The first ${t.bytes} bytes of this file (${t.pages} pages)`]]:[e]);return{...e,rows:n}}return e});return{...n,blocks:[...r?[r]:[],{type:`paragraph`,text:`Signatures and details for the ${t.pages}-page PDF document before this page.`},...i]}}const fs=e=>e.storage;function ps(e){let t=e.toBase64;if(typeof t==`function`)return t.call(e);let n=``;for(let t=0;t<e.length;t+=32768)n+=String.fromCharCode.apply(null,e.subarray(t,t+32768));return btoa(n)}function ms(e){try{let t=Uint8Array.fromBase64;if(typeof t==`function`)return t(e);let n=atob(e),r=new Uint8Array(n.length);for(let e=0;e<n.length;e++)r[e]=n.charCodeAt(e);return r}catch{return null}}function hs(e){let t=e[0];if(!t||e.length!==t.count)return null;let n=new Uint8Array(t.bytes),r=0;for(let[i,a]of e.entries()){if(!a||a.index!==i||a.sha256!==t.sha256||a.bytes!==t.bytes)return null;let e=ms(a.data);if(!e||r+e.length>n.length)return null;n.set(e,r),r+=e.length}return r===n.length?n:null}const gs=(e,t)=>`${e}:${t}`;function _s(e,t){let n=Math.max(1,Math.ceil(e.length/z));return Array.from({length:n},(r,i)=>({id:gs(t,i),data:{kind:`pdf-template`,contentType:`application/pdf`,index:i,count:n,bytes:e.length,sha256:t,data:ps(e.subarray(i*z,(i+1)*z))}}))}function vs(e,t,n,r,i){let a=Math.max(1,Math.ceil(t.length/z)),o=Math.floor(i/z);return Array.from({length:a},(i,s)=>({id:Ji(e,n,s),data:{envelopeId:e,kind:Fi,contentType:`application/pdf`,index:s,count:a,bytes:t.length,sha256:n,data:s<o&&r[s]?r[s].data:ps(t.subarray(s*z,(s+1)*z))}}))}const ys=e=>typeof e==`object`&&e&&!Array.isArray(e)?e:{},bs=/^[A-Za-z0-9_-]{1,100}$/,xs=(e,t)=>({ok:!1,error:{code:e,message:Xo[e]},...t?{issues:t}:{}}),Ss=e=>typeof e.user?.id==`string`&&e.user.id?e.user.id:void 0,Cs=e=>/limit|exceed/i.test(e instanceof Error?e.message:String(e)),ws=(e,t)=>({id:e,...t,pdf:{...t.pdf,ids:void 0}});async function Ts(e,t){let n=ys(e.input),r=typeof n.mediaId==`string`?n.mediaId.trim():``;if(!r||r.length>200)return H([{path:`mediaId`,code:`INVALID_INPUT`}]);let i=os(n.signerFields);if(i===null)return xs(`INVALID_FIELDS`,[{path:`signerFields`,code:`INVALID_FIELDS`}]);if(!t.media?.readBytes)return U(`NOT_FOUND`);let a=await t.media.get(r);if(!a)return U(`NOT_FOUND`);if(a.mimeType!==`application/pdf`&&!/\.pdf$/i.test(a.filename))return xs(`NOT_A_PDF`);if(typeof a.size==`number`&&a.size>Jo)return xs(`PDF_TOO_LARGE`);let o;try{o=await t.media.readBytes(r,{maxBytes:Jo})}catch(e){return Cs(e)?xs(`PDF_TOO_LARGE`):U(`NOT_FOUND`)}let s=await ts(o.bytes);if(!s.ok)return xs(s.error);let c=s.value.pages,l=ss(n.fields,c,i);if(!l.ok)return xs(`INVALID_FIELDS`,l.error);let u=(Ur(o.filename)??`document.pdf`).slice(0,120),d=n.name===void 0?u.replace(/\.pdf$/i,``)||u:Ur(n.name);if(!d)return xs(`INVALID_NAME`,[{path:`name`,code:`INVALID_NAME`}]);let f=await F(o.bytes),p=_s(o.bytes,f);await fs(t).pdf_files.putMany(p);let m=N(),h=`pdf_${crypto.randomUUID().replace(/-/g,``)}`,g={name:d,status:`active`,version:1,pdf:{sha256:f,bytes:o.bytes.length,filename:u,pages:c,ids:p.map(e=>e.id)},fields:l.value,signerFields:i,createdAt:m,updatedAt:m};return await fs(t).pdf_templates.put(h,g),{ok:!0,template:ws(h,g)}}async function Es(e,t){let n=ys(e.input),r=typeof n.id==`string`&&bs.test(n.id)?n.id:null;if(!r)return H([{path:`id`,code:`INVALID_INPUT`}]);let i=fs(t).pdf_templates,a=await i.get(r);if(!a||a.status!==`active`)return U(`TEMPLATE_NOT_FOUND`);let o=n.signerFields===void 0?a.signerFields:os(n.signerFields);if(o===null)return xs(`INVALID_FIELDS`,[{path:`signerFields`,code:`INVALID_FIELDS`}]);let s=ss(n.fields??a.fields,a.pdf.pages,o);if(!s.ok)return xs(`INVALID_FIELDS`,s.error);let c=n.name===void 0?a.name:Ur(n.name);if(!c)return xs(`INVALID_NAME`,[{path:`name`,code:`INVALID_NAME`}]);let l={...a,name:c,fields:s.value,signerFields:o,status:n.archived===!0?`archived`:`active`,version:a.version+1,updatedAt:N()};return await i.put(r,l),{ok:!0,template:ws(r,l)}}async function Ds(e,t){let n=ys(e.input),r=typeof n.templateId==`string`&&bs.test(n.templateId)?n.templateId:null,i=qr({templateId:`pdf`,title:n.title,signer:n.signer});if(!r)return H([{path:`templateId`,code:`INVALID_TEMPLATE_ID`}]);if(!i.ok)return H(i.error);if(n.otp!==void 0&&typeof n.otp!=`boolean`)return H([{path:`otp`,code:`INVALID_INPUT`}]);let{envelopes:a,signers:o,audit_events:s}=B(t),[c,l]=await Promise.all([fs(t).pdf_templates.get(r),t.settings.list()]);if(!c||c.status!==`active`)return U(`TEMPLATE_NOT_FOUND`);let u=Object.fromEntries(l.map(e=>[e.key,e.value])),d=crypto.randomUUID(),f=N(),p=cr(),m=Br(d,1),{signer:h,title:g}=i.value,_={kind:`pdf`,name:c.pdf.filename,bytes:c.pdf.bytes,pages:c.pdf.pages.length,templateId:r,ids:c.pdf.ids,sizes:c.pdf.pages,fields:c.fields},v={title:g??c.name,templateId:r,templateVersion:c.version,status:`sent`,routing:`parallel`,delivery:`email`,signer:h,signerEmail:h.email.toLowerCase(),fieldValues:{},...c.signerFields.length>0?{signerFields:c.signerFields}:{},signerIds:[m],docSha256:c.pdf.sha256,snapshot:null,document:_,expiresAt:N(Date.parse(f)+ha(u.expiryDays)*864e5),sentAt:f,completedAt:null,finalHash:null,piiSalt:p,createdAt:f,updatedAt:f,...Co(u,{integrations:!1},n.otp)},y=await va(o,{id:m,data:{envelopeId:d,order:1,role:`signer`,name:h.name,email:h.email,as:`self`,status:`pending`,tokenHash:``,createdAt:f}},A());await a.put(d,v);let b=Ss(e),x=li(v,`admin`,b);await s.putMany(await mr(d,[{...x,data:{...x.data,document:`pdf`,pdfBytes:c.pdf.bytes}},ui(v,`admin`,b)],p));let S=await rr(t,{signerId:m,envelope:v,token:y,senderSetting:u.senderName,now:Date.parse(f)}),{piiSalt:C,...ee}=v;return{ok:!0,envelope:{id:d,...ee},...S?{}:{invitation:`SITE_URL_MISSING`}}}const Os=e=>typeof e==`object`&&!!e&&!Array.isArray(e);function ks(e){if(!Os(e))return k([{path:``,code:`INVALID_INPUT`}]);let t=e.signers,n=[];(!Array.isArray(t)||t.length<2||t.length>10)&&n.push({path:`signers`,code:`INVALID_SIGNERS`}),e.routing!==`parallel`&&e.routing!==`sequential`&&n.push({path:`routing`,code:`INVALID_INPUT`}),e.otp!==void 0&&typeof e.otp!=`boolean`&&n.push({path:`otp`,code:`INVALID_INPUT`});let r=[],i;for(let[a,o]of(Array.isArray(t)&&n.length===0?t:[]).entries()){let t=qr({...e,signer:o});if(!t.ok){for(let e of t.error)e.path.startsWith(`signer.`)?n.push({...e,path:`signers.${a}.${e.path.slice(7)}`}):a===0&&n.push(e);continue}r.some(e=>e.email===t.value.signer.email)&&n.push({path:`signers.${a}.email`,code:`INVALID_SIGNER_EMAIL`}),r.push(t.value.signer),i??=t.value}return n.length>0||!i?k(n.length>0?n:[{path:``,code:`INVALID_INPUT`}]):O({draft:i,signers:r,routing:e.routing,...typeof e.otp==`boolean`?{otp:e.otp}:{}})}function As(e){return Object.fromEntries(e.flatMap((e,t)=>[[`signer${t+1}.name`,e.name],[`signer${t+1}.email`,e.email]]))}function js(e){return typeof e==`string`?e.slice(0,4e3).split(`
47
+ `).map(e=>e.trim()).filter(e=>e!==``).map(e=>{let t=/^(.*?)\s*<([^<>]*)>$/.exec(e);if(t)return{name:t[1].trim(),email:t[2].trim()};let n=e.lastIndexOf(`,`);return n>0?{name:e.slice(0,n).trim(),email:e.slice(n+1).trim()}:{name:e,email:``}}):[]}const Ms=(e,t)=>e===`parallel`||t===1,Ns=e=>`waiting:${e}`;function Ps(e,t,n){return e!==`sequential`||n.every(e=>e.order>=t.order||e.status===`signed`)}function Fs(e,t){return{type:`signer.invited`,at:t,actor:`system`,data:{signer:e.order},personal:{name:e.name,email:e.email}}}function Is(e,t,n){return{type:`reminder.sent`,at:t,actor:`system`,data:{signer:e.order,reminder:n},personal:{email:e.email}}}function Ls(e,t){let[n,r]=qa({at:t.signedAt??``,docSha256:e.docSha256??``,consentVersion:t.consentVersion??``,consentSha256:t.consentSha256??``,signature:t.signature??{kind:`typed`,sha256:``},signerName:t.name,who:{...t.ip?{ip:t.ip}:{},...t.ua?{ua:t.ua}:{}}});return[n,r].map(e=>({...e,data:{...e?.data,signer:t.order}}))}const Rs=[`sent`,`in_progress`];function zs(e,t,n,r){let i=(e,t)=>n.some(n=>n.type===e&&n.data.signer===t),a=t.filter(e=>e.data.status===`signed`&&!i(`signer.signed`,e.data.order)).flatMap(t=>Ls(e,t.data)),o=Rs.includes(e.status),s=o&&t.every(e=>e.data.status===`signed`);if(s)return a.push({type:`envelope.completed`,at:r,actor:`system`,data:{docSha256:e.docSha256}}),{inputs:a,complete:s};let c=t.find(e=>e.data.status!==`signed`);return o&&e.routing===`sequential`&&c?.data.waiting&&c.data.status===`pending`?(i(`signer.invited`,c.data.order)||a.push(Fs(c.data,r)),{inputs:a,complete:s,invite:c.id}):{inputs:a,complete:s}}function Bs(e){return Number.isSafeInteger(e)&&e>=1&&e<=30?e:3}function Vs(e,t,n){if(!Rs.includes(e.status)||t.status!==`pending`||t.waiting||(t.reminders??0)>=5||e.expiresAt!==null&&Date.parse(e.expiresAt)<=n.now)return!1;let r=Date.parse(t.remindedAt??t.invitedAt??e.sentAt??``);return Number.isFinite(r)&&r+n.cadenceDays*864e5<=n.now}function Hs(e){let t=Qn(e),n=`This reminder's link replaces the one in the earlier email.`;return{to:t.to,subject:`Reminder: ${t.subject}`,text:`${t.text}\n${n}\n`,html:`${t.html??``}\n<p>${n}</p>`}}const Us=e=>`invite-${e}`;function Ws(e,t){return{message:e,status:`pending`,attempts:0,nextAttemptAt:t,createdAt:t}}const Gs=(e,{piiSalt:t,...n})=>({id:e,...n});async function Ks(e,t){let n=ks(e.input);if(!n.ok)return H(n.error);let r=L(t);if(!r)return{ok:!1,error:{code:`SITE_URL_MISSING`,message:nr}};let{draft:i,signers:a,routing:o,otp:s}=n.value,{templates:c,envelopes:l,snapshots:u,signers:d,audit_events:f}=B(t),{templateId:p,templateVersion:m}=i,h=m===void 0?void 0:R(p,m),[g,_]=await Promise.all([c.getMany(h?[p,h]:[p]),t.settings.list()]),v=Jr(g.get(p),h?g.get(h):void 0,m);if(!v.ok)return U(`TEMPLATE_NOT_FOUND`);let y=e=>_.find(t=>t.key===e)?.value,b=N(),x=cr(),S=Qr({...i,fieldValues:{...i.fieldValues,...As(a)}},v.value,{now:b,piiSalt:x});if(!S.ok)return H(S.error);let C=crypto.randomUUID(),ee=await ai(C,{...S.value,routing:o},v.value,{now:b,tokenHash:``,expiryDays:ha(y(`expiryDays`))});if(!ee.ok)return Array.isArray(ee.error)?H(ee.error):U(`ENVELOPE_CLOSED`);let w={...ee.value.envelope,signerIds:a.map((e,t)=>Br(C,t+1)),...Co(Object.fromEntries(_.map(e=>[e.key,e.value])),v.value,s)};await u.putMany(ee.value.chunks);let T=new Map,E=[];for(let e=1;;e++){T=new Map,E=await Promise.all(a.map(async(e,t)=>{let n=w.signerIds[t],r=Ms(o,t+1)?A():void 0;return r&&T.set(n,r),{id:n,data:{envelopeId:C,order:t+1,role:`signer`,name:e.name,email:e.email,as:e.as,status:`pending`,tokenHash:r?await j(r):Ns(n),createdAt:b,...r?{invitedAt:b}:{waiting:!0}}}}));try{await d.putMany(E);break}catch(t){if(!ga(t)||e>=3)throw t}}await l.put(C,w);let D=typeof e.user?.id==`string`&&e.user.id?e.user.id:void 0,te=li(w,`admin`,D),O=E.filter(e=>T.has(e.id));await f.putMany(await mr(C,[{...te,data:{...te.data,routing:o,signers:a.length}},ui(w,`admin`,D),...O.map(e=>Fs(e.data,b))],x));let k=tr(t,y(`senderName`)),ne=Date.parse(b);return await I(t).putMany(O.map(e=>({id:Us(e.id),data:Ws(Qn({to:e.data.email,signerName:e.data.name,title:w.title,sender:k,link:`${r}/sign/${T.get(e.id)}`,expiresAt:w.expiresAt}),ne)}))),{ok:!0,envelope:Gs(C,w),signers:E.map(e=>({id:e.id,order:e.data.order,name:e.data.name,email:e.data.email,status:e.data.status}))}}const qs=1e3,Js=e=>e?.status===`active`&&e.public===!0;function Ys(e){let t=e.selfServeDailyCap;return typeof t==`number`&&Number.isInteger(t)&&t>=1&&t<=qs?t:50}function Xs(e){if(e!==void 0)return typeof e==`number`&&Number.isInteger(e)&&e>=1&&e<=qs?e:null}const Zs=e=>e.fields.filter(e=>!e.startsWith(`signer.`)&&!e.startsWith(`participant.`)),Qs=(e,t)=>`rl:ss-cap:${e}:${new Date(t).toISOString().slice(0,10)}`,$s=(e,t)=>`${e}:${(Math.floor(t/864e5)+1)*86400}`,ec=(e,t)=>{let n=new Set(Zs(t));return Object.keys(e).filter(e=>!n.has(e))},tc=`self-serve-`,nc=(e,t)=>({ok:!1,error:{code:e,message:t}}),rc=()=>nc(`TURNSTILE_NOT_CONFIGURED`,`Self-serve forms need the Turnstile site and secret keys in the settings.`),ic=(e,t)=>typeof e==`object`&&e?e[t]:void 0;async function ac(e,t,n){return!(await Sn({get:t=>e.kv.get(t),set:(t,n)=>e.kv.set(t,n)},t,n,{scope:`self-serve`,limit:5,windowSeconds:600,salt:`esign-self-serve/1`})).ok}const oc=e=>typeof e==`string`?e.trim():``;async function sc(e,t,n){let r=n.get(`licenceKey`),i=ce(await e.check({settings:{get:async()=>r??null},site:t.site}),`new`);return i.ok?null:oe(i.error).body}async function cc(e,t,n,r){let[i,a]=await Promise.all([B(e).templates.get(t),n]),o=await sc(r,e,a);if(o)return o;let s=a.get(`turnstileSiteKey`);return Js(i)?oc(s)?{ok:!0,template:{id:t,name:i.name,...i.description?{description:i.description}:{},fields:Zs(i)},turnstileSiteKey:oc(s)}:rc():U(`TEMPLATE_NOT_FOUND`)}const lc=async e=>new Map((await e.settings.list()).map(e=>[e.key,e.value])),uc=e=>async(t,n)=>{let r=oc(ic(t.input,`templateId`));if(!r||r.includes(`:`))return H([{path:`templateId`,code:`INVALID_TEMPLATE_ID`}]);if(ic(t.input,`describe`)===!0)return cc(n,r,lc(n),e);if(oc(ic(t.input,`website`))!==``)return{ok:!0,status:`check_email`};let i=qr({templateId:r,signer:{name:ic(t.input,`name`),email:ic(t.input,`email`)},fields:ic(t.input,`fields`)});if(!i.ok)return H(i.error);if(!L(n))return nc(`SITE_URL_MISSING`,`The site URL is not set, so the signing link cannot be emailed.`);let a=await lc(n),o=await sc(e,n,a);if(o)return o;let s=Date.now();if(await ac(n,t.requestMeta?.ip??`unknown`,s))return U(`RATE_LIMITED`);let c=a.get(`turnstileSecretKey`),l=a.get(`turnstileSiteKey`);if(!oc(c)||!oc(l))return rc();if(!(await zn((e,t)=>{if(!n.http)throw Error(`network:request is not granted`);return n.http.fetch(e,t)},{secret:oc(c),token:oc(ic(t.input,`turnstileToken`)),...t.requestMeta?.ip?{remoteIp:t.requestMeta.ip}:{}})).ok)return U(`TURNSTILE_FAILED`);let{templates:u,envelopes:d}=B(n),f=await u.get(r);if(!Js(f))return U(`TEMPLATE_NOT_FOUND`);let p=ec(i.value.fieldValues,f);if(p.length>0)return H(p.map(e=>({path:`fields.${e}`,code:`INVALID_FIELDS`})));let m=N(s),h=Qr(i.value,f,{now:m,piiSalt:cr()});if(!h.ok)return H(h.error);let g=Qs(r,s),_=Number.parseInt(await n.kv.get(g)??`0`,10);if((Number.isFinite(_)?_:0)>=Ys(f))return nc(`SELF_SERVE_FULL`,`This form has reached its limit for today.`);await n.kv.set(g,$s((Number.isFinite(_)?_:0)+1,s));let v=crypto.randomUUID();return await d.put(v,{...h.value,selfServe:!0}),await n.cron?.schedule(`${tc}${v}`,{schedule:m,data:{envelopeId:v}}),{ok:!0,status:`check_email`}};async function dc(e,t){let n=oc(ic(e.input,`id`)),r=ic(e.input,`enabled`),i=Xs(ic(e.input,`dailyCap`));if(!n||n.includes(`:`)||typeof r!=`boolean`||i===null)return H([{path:i===null?`dailyCap`:`enabled`,code:`INVALID_INPUT`}]);let{templates:a}=B(t),o=await a.get(n);if(!o||o.status!==`active`)return U(`TEMPLATE_NOT_FOUND`);let s={...o,public:r,...i===void 0?{}:{selfServeDailyCap:i},updatedAt:N()};return await a.put(n,s),{ok:!0,template:{id:n,public:r,selfServeDailyCap:s.selfServeDailyCap??50}}}const G=e=>({blocks:e}),K=(e,t=200)=>typeof e==`string`?e.trim().slice(0,t):``,q=(e,t,n)=>({severity:e,title:t,...n?{message:n}:{}}),fc=(e,t)=>_(e,t,{style:`secondary`});async function pc(e){let{items:t}=await B(e).templates.query({where:{status:`active`},limit:100});return t.sort((e,t)=>e.data.name.localeCompare(t.data.name))}const mc={running:`Running`,done:`Done`,cancelled:`Cancelled`},hc=()=>fc(`bulk.back`,`Back to bulk send`);async function gc(e,t=[],n={}){let[r,o]=await Promise.all([pc(e.ctx),To(e.ctx).query({where:{kind:`job`},orderBy:{createdAt:`desc`},limit:10})]),s=o.items.map(({id:e,data:t})=>{let n=t;return{template:n.templateName,title:n.title,status:mc[n.status],progress:po(n),created:n.createdAt,open:_(`bulk.open`,`Open`,{value:e})}});return G([i(`Bulk send`),...h([!L(e.ctx)&&q(`warning`,`Set the site URL`,nr)]),...t,a(`Send one template to many people, each in their own envelope. Paste a CSV: the first line is the header (name, email, then one column per placeholder of the template), then one line per recipient, up to 500. Every row is checked first; if any is wrong nothing is sent. Envelopes go out 10 at a time.`),w({fields:[x(`templateId`,`Template`,r.map(({id:e,data:t})=>({label:`${t.name} (columns: name, email${$a(t.fields).map(e=>`, ${e}`).join(``)})`,value:e})),n.templateId?{initialValue:n.templateId}:{}),y(`title`,`Envelope title (optional)`,n.title?{initialValue:n.title}:{}),y(`csv`,`Recipients (CSV)`,{multiline:!0,placeholder:`name,email
48
48
  Ada Lovelace,ada@example.com`,...n.csv?{initialValue:n.csv}:{}})],submit:{label:`Check and start`,actionId:`bulk.start`}}),i(`Recent bulk sends`),l({columns:[c(`template`,`Template`),c(`title`,`Title`),c(`status`,`Status`,`badge`),c(`progress`,`Progress`),c(`created`,`Started`,`relative_time`),c(`open`,``,`element`)],rows:s,pageActionId:`bulk.page`,emptyText:`No bulk sends yet.`})])}const _c=e=>`${e.replaceAll(`_`,` `).toLowerCase()}`;async function vc(e,t,n=[]){let r=await To(e.ctx).get(t);if(!r||r.kind!==`job`)return G([i(`Bulk send`),...h([q(`error`,`Bulk send not found`)]),g([hc()])]);let o=Math.max(0,r.total-r.sent-r.failed),d=r.status===`running`;return G([i(r.title),...n,s([{label:`Status`,value:mc[r.status]},{label:`Sent`,value:String(r.sent)},{label:`Failed`,value:String(r.failed)},{label:`Waiting`,value:String(r.status===`cancelled`?0:o)}]),u({label:po(r),value:r.sent+r.failed,max:r.total,min:0}),a(`Template: ${r.templateName}, version ${r.templateVersion}. Started ${r.createdAt.slice(0,16).replace(`T`,` `)} UTC. Invitations go through the outbox and arrive as it drains.`),r.failures.length>0?l({columns:[c(`recipient`,`Recipient`),c(`problem`,`Problem`)],rows:r.failures.map(e=>({recipient:`Recipient ${e.seq+1}`,problem:_c(e.code)})),pageActionId:`bulk.page`}):p({title:`No failures`,variant:`default`}),g([_(`bulk.open`,`Refresh`,{value:t,style:`secondary`}),...d?[_(`bulk.resume`,`Resume`,{value:t,style:`secondary`}),_(`bulk.cancel`,`Cancel the rest`,{value:t,style:`danger`,confirm:{title:`Cancel this bulk send?`,text:`Envelopes already sent stay sent. The rest are not sent and their details are deleted.`,confirm:`Cancel the rest`,deny:`Keep sending`}})]:[],hc()])])}function yc(e,t,n){return[...h([q(`error`,`Nothing was sent`,n)]),l({columns:[c(`problem`,`Problem`)],rows:e.map(e=>({problem:ro(e)})),pageActionId:`bulk.page`}),...t>e.length?[a(`Showing the first ${e.length} of ${t} problems.`)]:[]]}async function bc(e,t){let n={templateId:K(t.templateId),csv:K(t.csv,25e4),title:K(t.title)},r=await e.startBulk({templateId:n.templateId,csv:typeof t.csv==`string`?t.csv:``,...n.title?{title:n.title}:{}});if(r.ok!==!0){let t=Array.isArray(r.issues)?r.issues:[],i=typeof r.total==`number`?r.total:t.length,a=r.error?.message??`The bulk send was refused.`;return gc(e,t.length>0?yc(t,i,a):h([q(`error`,`Not started`,a)]),n)}let i=r.job;return vc(e,i.id,h([q(`info`,`Bulk send started`,`${i.total} recipients checked and queued.`)]))}async function xc(e,t){return(await ko({input:{id:t}},e.ctx)).ok===!0?vc(e,t,h([q(`info`,`The bulk send was cancelled`,`No more envelopes are sent; the remaining details are deleted as the job's next steps run.`)])):vc(e,t,h([q(`error`,`Not cancelled`,`That bulk send was not found.`)]))}async function Sc(e,t){let n=await To(e.ctx).get(t);if(!n||n.kind!==`job`||n.status!==`running`)return vc(e,t);let r=Math.floor((n.sent+n.failed)/10);return await e.ctx.cron?.schedule(lo(t,Math.min(r,n.pages-1)),{schedule:N(e.now)}),vc(e,t,h([q(`info`,`Resumed`,`The next batch is queued.`)]))}const Cc=e=>e.type===`page_load`?e.page===`/bulk`:e.action_id===`bulk.start`||e.action_id.startsWith(`bulk.`);async function wc(e,t){if(t.type===`page_load`)return gc(e);if(t.type===`form_submit`)return bc(e,t.values);let n=K(t.value,100);switch(t.action_id){case`bulk.open`:return vc(e,n);case`bulk.cancel`:return xc(e,n);case`bulk.resume`:return Sc(e,n);default:return gc(e)}}const Tc=/^([A-Za-z0-9_-]{1,100}):s(\d{1,2})$/,Ec=[`sent`,`in_progress`],Dc=(e,t)=>({ok:!1,error:{code:e,message:t}});async function Oc(e,t,n=Date.now()){let r=e.input?.signerId,i=typeof r==`string`?Tc.exec(r):null;if(!i||typeof r!=`string`)return H([{path:`signerId`,code:`INVALID_INPUT`}]);let a=i[1],o=L(t);if(!o)return Dc(`SITE_URL_MISSING`,nr);let{envelopes:s,signers:c,audit_events:l}=B(t),[u,d]=await Promise.all([s.get(a),c.get(r)]),f=d;if(!u||!f||f.envelopeId!==a)return U(`NOT_FOUND`);if(!Ec.includes(u.status))return Dc(`ENVELOPE_CLOSED`,`The envelope is no longer open for signing.`);if(f.status!==`pending`)return Dc(`SIGNER_DONE`,`This signer has already signed or declined.`);if(f.waiting)return Dc(`SIGNER_NOT_INVITED`,`This signer has not been invited yet: it is not their turn.`);let p=tr(t,await t.settings.get(`senderName`)),m=N(n),h=await _a(A(),void 0,e=>c.updateIf(r,{where:{status:`pending`,tokenHash:f.tokenHash},set:{tokenHash:e,invitedAt:m}}));if(!h.value.applied)return Dc(`SIGNER_CHANGED`,`The signer's status changed. Open the envelope again.`);if(await I(t).put(Us(r),Ws(Qn({to:f.email,signerName:f.name,title:u.title,sender:p,link:`${o}/sign/${h.token}`,expiresAt:u.expiresAt}),n)),!(await gr(l,a,Fs(f,m),{salt:u.piiSalt})).ok)throw Error(`audit chain contention`);return{ok:!0,signer:{id:r,order:f.order,name:f.name,email:f.email}}}const kc={INVALID_SIGNERS:`Enter 2 to 10 signers, one per line.`,INVALID_SIGNER_EMAIL:`Enter a valid email address.`,INVALID_SIGNER_NAME:`Enter the signer's name.`,MISSING_FIELD:`A template field has no value.`,INVALID_FIELDS:`A field value is too long.`,INVALID_TITLE:`The title is too long.`};function Ac(e){let t=e.issues??[];return t.length>0?t.map(e=>{let t=/^signers\.(\d+)\./.exec(e.path??``);return`${t?`Signer ${Number(t[1])+1}: `:e.path?.startsWith(`fields.`)?`${e.path.slice(7)}: `:``}${kc[e.code??``]??e.code??`invalid`}`}).join(` `):e.error?.message??`The envelope was refused.`}const jc=/^(signer\d*|participant)\./,Mc=e=>_(`envelope.open`,`Open envelope`,{value:e}),Nc=()=>fc(`envelopes.back`,`Back to envelopes`);async function Pc(e){let t=await pc(e.ctx);return[i(`Send to several signers`),a(`One envelope for 2 to 10 signers. In parallel everyone is invited at once; in sequence each signer is invited after the one before has signed. A template can use {{signer1.name}}, {{signer2.email}} and so on for each signer.`),w({fields:[x(`templateId`,`Template`,t.map(({id:e,data:t})=>({label:t.name,value:e}))),x(`routing`,`Signing order`,[{label:`All at once (parallel)`,value:`parallel`},{label:`One after the other (sequential)`,value:`sequential`}],{initialValue:`parallel`})],submit:{label:`Continue`,actionId:`several.pick`}})]}function Fc(e,t,n,r=[],o={}){let s=n.fields.filter(e=>!jc.test(e));return G([i(`Send to several signers: ${n.name}`),...r,a(t===`sequential`?`Signers sign in the order listed; each is invited after the one before has signed.`:`Every signer is invited now and they can sign in any order.`),w({fields:[y(`title`,`Title`,{initialValue:K(o.title)||n.name}),y(`signers`,`Signers (2 to 10, one per line: Name <email>)`,{multiline:!0,placeholder:`Ada Lovelace <ada@example.com>
49
- Grace Hopper <grace@example.com>`,...typeof o.signers==`string`?{initialValue:o.signers}:{}}),...s.map(e=>y(`field:${e}`,e,typeof o[`field:${e}`]==`string`?{initialValue:o[`field:${e}`]}:{})),x(`otp`,`Emailed code before signing`,[{label:`As set in Settings`,value:``},{label:`Require a code`,value:`yes`},{label:`No code`,value:`no`}],{initialValue:K(o.otp)})],submit:{label:`Send for signature`,actionId:`several.send`},blockId:`several:${e}:${t}`}),g([Nc()])])}async function Ic(e,t){let n=K(t.templateId),r=K(t.routing)===`sequential`?`sequential`:`parallel`,a=n?await B(e.ctx).templates.get(n):null;return!a||a.status!==`active`?G([i(`Send to several signers`),...h([q(`error`,`Choose a template first`)]),g([Nc()])]):Fc(n,r,a)}async function Lc(e,t,n){let[,r=``,a=`parallel`]=(t??``).split(`:`);if(!r)return G(h([q(`error`,`Choose a template first`)]));let o={};for(let[e,t]of Object.entries(n))e.startsWith(`field:`)&&(o[e.slice(6)]=typeof t==`string`?t:``);let s=K(n.otp),c=K(n.title),l=js(n.signers),u=await e.sendSeveral({templateId:r,routing:a,signers:l,fields:o,...c?{title:c}:{},...s===`yes`?{otp:!0}:s===`no`?{otp:!1}:{}});if(u.ok!==!0){let t=await B(e.ctx).templates.get(r),i=h([q(`error`,`Not sent`,Ac(u))]);return t?Fc(r,a,t,i,n):G([...i,g([Nc()])])}let d=u.envelope.id;return G([i(`Send to several signers`),...h([q(`info`,`Envelope sent to ${l.length} signers`,a===`sequential`?`The first signer's invitation is queued; each next signer is invited after the one before has signed.`:`Every signer's invitation is queued.`)]),g([Mc(d),Nc()])])}async function Rc(e,t){let{envelopes:n,signers:r}=B(e.ctx),o=Array.from({length:10},(e,n)=>zr(t,n+1)),[s,u]=await Promise.all([n.get(t),r.getMany(o)]),d=o.flatMap(e=>{let t=u.get(e);return t?[{id:e,data:t}]:[]});if(!s||d.length<2)return[];let f=s.status===`sent`||s.status===`in_progress`;return[i(`Signers`),a(`${s.routing===`sequential`?`Signing in order`:`Signing in any order`}. Resend gives a signer a fresh link and cancels their old one.`),l({columns:[c(`order`,`#`),c(`signer`,`Signer`),c(`status`,`Status`,`badge`),c(`link`,`Link`),c(`resend`,``,`element`)],rows:d.map(({id:e,data:t})=>{let n=f&&t.status===`pending`&&!t.waiting;return{order:String(t.order),signer:`${t.name} <${t.email}>`,status:t.waiting?`waiting`:t.status,link:t.waiting?`Not their turn yet`:t.invitedAt?`Invited ${t.invitedAt.slice(0,10)}`:`Invited`,resend:n?_(`signer.resend`,`Resend`,{value:e,style:`secondary`}):``}}),pageActionId:`signers.page`})]}async function zc(e,t){let n=await Oc({input:{signerId:t}},e.ctx,e.now),r=t.replace(/:s\d+$/,``);if(n.ok!==!0){let e=n.error?.message??`Only a signer who has not signed and holds a live link can be resent.`;return G([i(`Envelope`),...h([q(`error`,`Not resent`,e)]),g([Mc(r),Nc()])])}let a=n.signer;return G([i(`Envelope`),...h([q(`info`,`Invitation queued`,`${a.name} <${a.email}> will get a new email with a new signing link. Their earlier link no longer works.`)]),g([Mc(r),Nc()])])}const Bc=e=>e===`several.pick`||e===`several.send`||e===`signer.resend`;async function Vc(e,t){return t.action_id===`several.pick`?Ic(e,t.values??{}):t.action_id===`several.send`?Lc(e,t.block_id,t.values??{}):zc(e,K(t.value,150))}const Hc=()=>fc(`pdft.back`,`Back to PDF templates`),Uc=e=>e>=1048576?`${(e/1048576).toFixed(1)} MB`:`${Math.max(1,Math.round(e/1024))} KB`,Wc=e=>{let t=(e.issues??[]).map(e=>e.path).filter(Boolean);return`${e.error?.message??`The change was refused.`}${t.length?` (${t.join(`, `)})`:``}`};async function Gc(e,t=[]){let{items:n}=await fs(e.ctx).pdf_templates.query({where:{status:`active`},limit:100}),r=[...n].sort((e,t)=>e.data.name.localeCompare(t.data.name));return G([i(`PDF templates`),...t,a(`Upload a PDF from the media library, then set where the signature, name, date and the signer's entries are stamped. The signer reads the PDF itself; the signed copy is that file, unchanged, with the stamps and a certificate added after it.`),l({columns:[c(`name`,`Template`),c(`pages`,`Pages`),c(`size`,`Size`),c(`fields`,`Fields`),c(`open`,``,`element`)],rows:r.map(({id:e,data:t})=>({name:t.name,pages:String(t.pdf.pages.length),size:Uc(t.pdf.bytes),fields:String(t.fields.length),open:_(`pdft.open`,`Open`,{value:e})})),pageActionId:`pdft.page`,emptyText:`No PDF templates yet.`}),g([ee(`pdft.upload`,`Upload a PDF (at most 3 MB)`,{mimeTypeFilter:`application/pdf`})])])}const Kc=e=>e.map(e=>`${e.key} | ${e.label}${e.required?` | required`:``}`).join(`
49
+ Grace Hopper <grace@example.com>`,...typeof o.signers==`string`?{initialValue:o.signers}:{}}),...s.map(e=>y(`field:${e}`,e,typeof o[`field:${e}`]==`string`?{initialValue:o[`field:${e}`]}:{})),x(`otp`,`Emailed code before signing`,[{label:`As set in Settings`,value:``},{label:`Require a code`,value:`yes`},{label:`No code`,value:`no`}],{initialValue:K(o.otp)})],submit:{label:`Send for signature`,actionId:`several.send`},blockId:`several:${e}:${t}`}),g([Nc()])])}async function Ic(e,t){let n=K(t.templateId),r=K(t.routing)===`sequential`?`sequential`:`parallel`,a=n?await B(e.ctx).templates.get(n):null;return!a||a.status!==`active`?G([i(`Send to several signers`),...h([q(`error`,`Choose a template first`)]),g([Nc()])]):Fc(n,r,a)}async function Lc(e,t,n){let[,r=``,a=`parallel`]=(t??``).split(`:`);if(!r)return G(h([q(`error`,`Choose a template first`)]));let o={};for(let[e,t]of Object.entries(n))e.startsWith(`field:`)&&(o[e.slice(6)]=typeof t==`string`?t:``);let s=K(n.otp),c=K(n.title),l=js(n.signers),u=await e.sendSeveral({templateId:r,routing:a,signers:l,fields:o,...c?{title:c}:{},...s===`yes`?{otp:!0}:s===`no`?{otp:!1}:{}});if(u.ok!==!0){let t=await B(e.ctx).templates.get(r),i=h([q(`error`,`Not sent`,Ac(u))]);return t?Fc(r,a,t,i,n):G([...i,g([Nc()])])}let d=u.envelope.id;return G([i(`Send to several signers`),...h([q(`info`,`Envelope sent to ${l.length} signers`,a===`sequential`?`The first signer's invitation is queued; each next signer is invited after the one before has signed.`:`Every signer's invitation is queued.`)]),g([Mc(d),Nc()])])}async function Rc(e,t){let{envelopes:n,signers:r}=B(e.ctx),o=Array.from({length:10},(e,n)=>Br(t,n+1)),[s,u]=await Promise.all([n.get(t),r.getMany(o)]),d=o.flatMap(e=>{let t=u.get(e);return t?[{id:e,data:t}]:[]});if(!s||d.length<2)return[];let f=s.status===`sent`||s.status===`in_progress`;return[i(`Signers`),a(`${s.routing===`sequential`?`Signing in order`:`Signing in any order`}. Resend gives a signer a fresh link and cancels their old one.`),l({columns:[c(`order`,`#`),c(`signer`,`Signer`),c(`status`,`Status`,`badge`),c(`link`,`Link`),c(`resend`,``,`element`)],rows:d.map(({id:e,data:t})=>{let n=f&&t.status===`pending`&&!t.waiting;return{order:String(t.order),signer:`${t.name} <${t.email}>`,status:t.waiting?`waiting`:t.status,link:t.waiting?`Not their turn yet`:t.invitedAt?`Invited ${t.invitedAt.slice(0,10)}`:`Invited`,resend:n?_(`signer.resend`,`Resend`,{value:e,style:`secondary`}):``}}),pageActionId:`signers.page`})]}async function zc(e,t){let n=await Oc({input:{signerId:t}},e.ctx,e.now),r=t.replace(/:s\d+$/,``);if(n.ok!==!0){let e=n.error?.message??`Only a signer who has not signed and holds a live link can be resent.`;return G([i(`Envelope`),...h([q(`error`,`Not resent`,e)]),g([Mc(r),Nc()])])}let a=n.signer;return G([i(`Envelope`),...h([q(`info`,`Invitation queued`,`${a.name} <${a.email}> will get a new email with a new signing link. Their earlier link no longer works.`)]),g([Mc(r),Nc()])])}const Bc=e=>e===`several.pick`||e===`several.send`||e===`signer.resend`;async function Vc(e,t){return t.action_id===`several.pick`?Ic(e,t.values??{}):t.action_id===`several.send`?Lc(e,t.block_id,t.values??{}):zc(e,K(t.value,150))}const Hc=()=>fc(`pdft.back`,`Back to PDF templates`),Uc=e=>e>=1048576?`${(e/1048576).toFixed(1)} MB`:`${Math.max(1,Math.round(e/1024))} KB`,Wc=e=>{let t=(e.issues??[]).map(e=>e.path).filter(Boolean);return`${e.error?.message??`The change was refused.`}${t.length?` (${t.join(`, `)})`:``}`};async function Gc(e,t=[]){let{items:n}=await fs(e.ctx).pdf_templates.query({where:{status:`active`},limit:100}),r=[...n].sort((e,t)=>e.data.name.localeCompare(t.data.name));return G([i(`PDF templates`),...t,a(`Upload a PDF from the media library, then set where the signature, name, date and the signer's entries are stamped. The signer reads the PDF itself; the signed copy is that file, unchanged, with the stamps and a certificate added after it.`),l({columns:[c(`name`,`Template`),c(`pages`,`Pages`),c(`size`,`Size`),c(`fields`,`Fields`),c(`open`,``,`element`)],rows:r.map(({id:e,data:t})=>({name:t.name,pages:String(t.pdf.pages.length),size:Uc(t.pdf.bytes),fields:String(t.fields.length),open:_(`pdft.open`,`Open`,{value:e})})),pageActionId:`pdft.page`,emptyText:`No PDF templates yet.`}),g([ee(`pdft.upload`,`Upload a PDF (at most 3 MB)`,{mimeTypeFilter:`application/pdf`})])])}const Kc=e=>e.map(e=>`${e.key} | ${e.label}${e.required?` | required`:``}`).join(`
50
50
  `);function qc(e){return e.split(/\r?\n/).map(e=>e.trim()).filter(Boolean).map(e=>{let[t,n,r]=e.split(`|`).map(e=>e.trim());return{key:t,label:n??``,...r?.toLowerCase()===`required`?{required:!0}:{}}})}async function Jc(e,t,n=[]){let r=await fs(e.ctx).pdf_templates.get(t);if(!r||r.status!==`active`)return G([i(`PDF templates`),...h([q(`error`,`Template not found`)]),g([Hc()])]);let o=r.pdf.pages.map((e,t)=>`page ${t+1}: ${e.w} x ${e.h}`).join(`, `);return G([i(`PDF template: ${r.name}`),...n,a(`${r.pdf.filename}, ${Uc(r.pdf.bytes)}, SHA-256 ${r.pdf.sha256}. Page sizes in points: ${o}.`),w({fields:[y(`name`,`Name`,{initialValue:r.name}),y(`signerFields`,`Signer fields: key | label | required (one per line)`,{initialValue:Kc(r.signerFields),multiline:!0}),y(`fields`,`Fields: kind page x y width height [key] [signer=n] (kinds: signature, name, date, text)`,{initialValue:ls(r.fields),multiline:!0,placeholder:`signature 1 72 650 200 50
51
51
  name 1 72 710 200 18
52
- date 1 320 710 120 18`})],submit:{label:`Save`,actionId:`pdft.save`},blockId:`pdft:${t}`}),w({fields:[y(`signerName`,`Signer's name`),y(`signerEmail`,`Signer's email`),y(`title`,`Title (optional)`)],submit:{label:`Send for signature`,actionId:`pdft.send`},blockId:`pdft-send:${t}`}),g([_(`pdft.archive`,`Archive`,{value:t,style:`danger`}),Hc()])])}const Yc=(e,t)=>e?.startsWith(t)?e.slice(t.length):``,Xc=(e,t,n)=>e.pdfTemplates(t,n);async function Zc(e,t){let n=typeof t==`string`?t.trim():K(t?.id);if(!n)return Gc(e,h([q(`error`,`Choose a PDF first`)]));let r=await Xc(e,`upload`,{mediaId:n});if(r.ok!==!0)return Gc(e,h([q(`error`,`Not uploaded`,Wc(r))]));let i=r.template;return Jc(e,i.id,h([q(`info`,`Uploaded`,`Now set the fields to stamp, then send it.`)]))}async function Qc(e,t){if(t.type===`page_load`)return Gc(e);if(t.type===`block_action`){if(t.action_id===`pdft.upload`)return Zc(e,t.value);let n=K(t.value);if(t.action_id===`pdft.open`&&n)return Jc(e,n);if(t.action_id===`pdft.archive`&&n){let t=await Xc(e,`update`,{id:n,archived:!0});return Gc(e,h([t.ok?q(`info`,`Template archived`):q(`error`,`Not archived`,Wc(t))]))}return Gc(e)}let n=t.values;if(t.action_id===`pdft.save`){let r=Yc(t.block_id,`pdft:`),i=cs(typeof n.fields==`string`?n.fields:``);if(!i.ok)return Jc(e,r,h([q(`error`,`Not saved`,`Check field line ${i.error.join(`, `)}.`)]));let a=await Xc(e,`update`,{id:r,name:K(n.name),fields:i.value,signerFields:qc(typeof n.signerFields==`string`?n.signerFields:``)});return Jc(e,r,h([a.ok?q(`info`,`Saved`):q(`error`,`Not saved`,Wc(a))]))}if(t.action_id===`pdft.send`){let r=Yc(t.block_id,`pdft-send:`),i=await Xc(e,`send`,{templateId:r,signer:{name:K(n.signerName),email:K(n.signerEmail,254)},...K(n.title)?{title:K(n.title)}:{}});return i.ok===!0?Jc(e,r,h([i.invitation===`SITE_URL_MISSING`?q(`warning`,`Sent, but no email`,`Set the site URL so invitations can link to the signing page.`):q(`info`,`Sent for signature`)])):Jc(e,r,h([q(`error`,`Not sent`,Wc(i))]))}return Gc(e)}const $c=e=>e.type===`page_load`?e.page===`/pdf-templates`:e.action_id.startsWith(`pdft.`),el=()=>fc(`selfserve.back`,`Back to self-serve forms`);async function tl(e,t=[]){let[n,r,o]=await Promise.all([pc(e.ctx),e.ctx.settings.get(`turnstileSiteKey`),e.ctx.settings.get(`turnstileSecretKey`)]),s=typeof r==`string`&&r!==``&&typeof o==`string`&&o!==``;return G([i(`Self-serve forms`),...h([!s&&q(`warning`,`Turnstile is not set up`,`A public form needs both Cloudflare Turnstile keys in Settings. Until then the form on your page says it is unavailable.`)]),...t,a(`Mark a template here, then add the Self-serve request block to a page and pick the template. A visitor types their name, email address and the template's fields; the signing link goes only to that address. The cap is how many visitors can start in a day (UTC).`),l({columns:[c(`name`,`Template`),c(`state`,`Self-serve`,`badge`),c(`cap`,`Per day`),c(`edit`,``,`element`)],rows:n.map(({id:e,data:t})=>({name:t.name,state:Js(t)?`On`:`Off`,cap:Js(t)?String(Ys(t)):``,edit:_(`selfserve.open`,`Edit`,{value:e})})),pageActionId:`selfserve.page`,emptyText:`No active templates. Create one on the Templates page.`})])}async function nl(e,t,n=[]){let r=await B(e.ctx).templates.get(t);return!r||r.status!==`active`?G([i(`Self-serve forms`),...h([q(`error`,`Template not found`)]),g([el()])]):G([i(`Self-serve: ${r.name}`),...n,w({fields:[S(`enabled`,`Offer this template to visitors`,{initialValue:Js(r)}),b(`dailyCap`,`Visitors per day`,{initialValue:r.selfServeDailyCap??50,min:1,max:qs})],submit:{label:`Save`,actionId:`selfserve.save`},blockId:`selfserve:${t}`}),g([el()])])}async function rl(e,t,n){let r=t?.startsWith(`selfserve:`)?t.slice(10):``;if(!r)return tl(e,h([q(`error`,`Choose a template first`)]));let i=n.enabled===!0,a=n.dailyCap,o=typeof a==`number`?a:typeof a==`string`&&a.trim()!==``?Number(a):void 0,s=await e.markSelfServe({id:r,enabled:i,...o===void 0?{}:{dailyCap:o}});if(s.ok!==!0)return nl(e,r,h([q(`error`,`Not saved`,s.error?.code===`BAD_REQUEST`?`The daily cap must be a whole number from 1 to ${qs}.`:s.error?.message??`The change was refused.`)]));let c=s.template;return tl(e,h([q(`info`,c.public?`Self-serve is on`:`Self-serve is off`,c.public?`Up to ${c.selfServeDailyCap} visitors a day can start from this template.`:`Visitors can no longer start from this template.`)]))}const il=e=>e.type===`page_load`?e.page===`/self-serve`:e.action_id.startsWith(`selfserve.`);async function al(e,t){return t.type===`page_load`?tl(e):t.type===`form_submit`?rl(e,t.block_id,t.values):t.action_id===`selfserve.open`?nl(e,K(t.value,200)):tl(e)}const ol=e=>typeof e==`function`?e:e.handler;function sl(e){try{return new URL(e.request?.url??``).origin}catch{return`http://localhost`}}function cl(e){let t=(t,n)=>ol(e.gate(t,{handler:n})),n=t(`esign/envelope-send`,Ks),r=t(`esign/envelope-send`,Oo),i=t(`new`,dc),a={upload:t(`new`,Ts),update:t(`new`,Es),send:t(`esign/envelope-send`,Ds)};return e=>{let t=ol(e),o=async(e,o)=>{let s=e.input,c=e.user??null,l=e=>t=>e({input:t,user:c},o),u={ctx:o,origin:sl(e),now:Date.now(),user:c,sendSeveral:l(n),startBulk:l(r),markSelfServe:l(i),pdfTemplates:(e,t)=>l(a[e])(t)};if(Cc(s))return wc(u,s);if(il(s))return al(u,s);if($c(s))return Qc(u,s);if(s.type!==`page_load`&&Bc(s.action_id))return Vc(u,s);let d=s.type===`page_load`&&s.page===`/envelopes`||s.type===`block_action`&&s.action_id===`envelopes.back`?()=>Pc(u):s.type===`block_action`&&s.action_id===`envelope.open`?()=>Rc(u,String(s.value??``).trim().slice(0,200)):null;if(!d)return t(e,o);let[f,p]=await Promise.all([t(e,o),d()]),m=f?.blocks;return Array.isArray(m)&&p.length>0?{...f,blocks:[...m,...p]}:f};return typeof e==`function`?o:{...e,handler:o}}}async function ll(e,t,n,r){let i=To(e),a=await i.getMany([t,oo(t),ao(t,n),so(t)]),o=a.get(t),s=a.get(ao(t,n));if(!o||o.kind!==`job`||!s)return`skipped`;let c=N(r),l=n+1>=o.pages,u=async()=>{await e.cron?.schedule(lo(t,n+1),{schedule:c})},d=L(e);if(o.status===`cancelled`||a.has(so(t))||!d)return await i.deleteMany([ao(t,n),...l?[oo(t),so(t)]:[]]),(o.status!==`cancelled`||!l)&&await i.putMany([{id:t,data:{...o,status:`cancelled`,updatedAt:c}}]),l||await u(),`cancelled`;let f=a.get(oo(t))?.template,p=s.rows.filter(e=>e.status===`pending`),m=new Map,h=[],g={chunks:[],signers:[],envelopes:[],audit:[],mail:[]},_=tr(e,o.senderName);await Promise.all(p.map(async e=>{let n=t=>{m.set(e.seq,{seq:e.seq,status:`failed`,code:t}),h.push({seq:e.seq,code:t})};if(!f||!e.name||!e.email)return n(`TEMPLATE_NOT_FOUND`);let i=co(t,e.seq),a=cr(),s=Zr({templateId:o.templateId,templateVersion:o.templateVersion,title:o.title,signer:{name:e.name,email:e.email,as:`self`},fieldValues:e.fields??{}},f,{now:c,piiSalt:a});if(!s.ok)return n(s.error[0]?.code??`BAD_REQUEST`);let l=A(),u=await ii(i,s.value,f,{now:c,tokenHash:await j(l),expiryDays:o.expiryDays});if(!u.ok)return n(Array.isArray(u.error)?u.error[0]?.code??`BAD_REQUEST`:`ENVELOPE_CLOSED`);let p={...u.value.envelope,...o.otp?{otp:!0}:{}},v=ci(p,`admin`,o.createdBy),y=[{...v,data:{...v.data,source:`bulk`}},li(p,`admin`,o.createdBy)];g.chunks.push(...u.value.chunks),g.signers.push(u.value.signer),g.envelopes.push({id:i,data:p}),g.audit.push(...await mr(i,y,a)),g.mail.push({id:Us(u.value.signer.id),data:Ws(Qn({to:e.email,signerName:e.name,title:p.title,sender:_,link:`${d}/sign/${l}`,expiresAt:p.expiresAt}),r)}),m.set(e.seq,{seq:e.seq,status:`sent`,envelopeId:i})}));let v=B(e),y=async(e,t)=>{t.length>0&&await e.putMany(t)};await y(v.snapshots,g.chunks),await y(v.signers,g.signers),await y(v.envelopes,g.envelopes),await y(v.audit_events,g.audit),await y(I(e),g.mail);let b=s.rows.map(e=>m.get(e.seq)??e),x=[...m.values()].filter(e=>e.status===`sent`).length,S=[{id:t,data:{...o,sent:o.sent+x,failed:o.failed+h.length,failures:[...o.failures,...h].slice(0,50),status:l?`done`:`running`,updatedAt:c}},{id:ao(t,n),data:{...s,rows:b}}];return await i.putMany(S),l?await i.deleteMany([oo(t)]):await u(),`sent`}async function ul(e,t,n=Date.now()){let r=fo(e.name);return r?(await ll(t,r.jobId,r.page,n),!0):!1}const dl=`expire`,fl=`expire-more`;async function pl(e,t){if(e.name!==dl&&e.name!==fl)return!1;let{envelopes:n}=B(t),r=N(),i=await n.query({where:{status:{in:[`sent`,`in_progress`]},expiresAt:{lt:r}},orderBy:{expiresAt:`asc`},limit:2});for(let{id:e,data:a}of i.items){let i=await R(n,e,a.status,`expired`,{closedAt:r,updatedAt:r});i.ok&&await xa(t,e,i.value,{type:`envelope.expired`,at:r,actor:`system`})}return i.hasMore&&await t.cron?.schedule(fl,{schedule:N(Date.now()+6e4)}),!0}function ml(e){if(typeof e!=`string`)return null;let t=new TextEncoder().encode(e.trim());return t.length>=32?t:null}const hl=`intent-finish-`,gl=e=>`${hl}${e}`;function _l(e,t,n){return e?.schedule(gl(t),{schedule:N(n),data:{envelopeId:t}})}async function vl(e,t){let n=await te(e),r=await crypto.subtle.sign(`HMAC`,n,new TextEncoder().encode(`esign-invite/1.${t}`));return E(new Uint8Array(r))}async function yl(e,t,n){let{envelopes:r,templates:i,snapshots:a,signers:o,audit_events:s}=B(e),c=await r.get(t);if(!c||c.status!==`draft`||c.delivery!==`email`||!c.clientId)return`skipped`;let l=z(c.templateId,c.templateVersion),[u,d]=await Promise.all([i.getMany([c.templateId,l]),e.settings.list()]),f=Object.fromEntries(d.map(e=>[e.key,e.value])),p=qr(u.get(c.templateId),u.get(l),c.templateVersion);if(!p.ok)return`skipped`;let m=ml(f.integrationMasterKey);if(!m)return`skipped`;let h=await vl(m,t),g=await ii(t,c,p.value,{now:N(n),tokenHash:await j(h),expiryDays:ha(f.expiryDays)});if(!g.ok)return`skipped`;await a.putMany(g.value.chunks);let _=await va(o,g.value.signer,h);await rr(e,{signerId:g.value.signer.id,envelope:g.value.envelope,token:_,senderSetting:f.senderName,now:n});let v=[ci(c,`integration`),li(g.value.envelope,`integration`)];return await s.putMany(await mr(t,v,c.piiSalt)),(await R(r,t,`draft`,`sent`,g.value.envelope)).ok?`sent`:`skipped`}async function bl(e,t){if(!e.name.startsWith(hl))return!1;let n=e.data?.envelopeId;return typeof n==`string`&&n.length>0&&await yl(t,n,Date.now()),!0}const xl=`nonce-sweep`,Sl=`nonce-sweep-more`;async function Cl(e){let{nonces:t,cron:n,now:r,page:i=100,pages:a=3}=e,o=N(r),s=0,c=!1;for(let e=0;e<a;e++){let e=await t.query({where:{expiresAt:{lt:o}},orderBy:{expiresAt:`asc`},limit:i});if(e.items.length===0||(s+=await t.deleteMany(e.items.map(e=>e.id)),c=e.hasMore===!0,!c))break}return c&&await n?.schedule(Sl,{schedule:N(r+6e4)}),{deleted:s,more:c}}async function wl(e,t){if(e.name!==xl&&e.name!==Sl)return!1;let n=t.storage.nonces;return await Cl({nonces:n,cron:t.cron,now:Date.now()}),!0}const Tl=`retention`,El=`retention-more`,Dl=`cron:retention`,Ol=e=>e.status===`sent`||e.status===`in_progress`,kl=e=>Ol(e)?null:Date.parse(e.completedAt??e.closedAt??e.updatedAt),Al=(e,t,n,r)=>{let i=e.find(e=>e.key===t)?.value;return typeof i==`number`&&Number.isFinite(i)?Math.min(r,Math.max(1,Math.round(i))):n};function jl(e,t){let n=new Date(t);n.setUTCMonth(n.getUTCMonth()-Al(e,`retentionPersonalDataMonths`,12,120));let r=new Date(t);return r.setUTCFullYear(r.getUTCFullYear()-Al(e,`retentionSignedRecordsYears`,7,50)),{p:Math.max(n.getTime(),r.getTime()),r:r.getTime()}}function Ml(e,t){let{name:n,email:r,ip:i,ua:a,signature:o,fieldValues:s,declineReason:c,copyTokenHash:l,participant:u,...d}=t;return{...d,name:``,email:``,tokenHash:`purged:${e}`,...o?{signature:{kind:o.kind,sha256:o.sha256}}:{}}}function Nl(e,t){let{piiSalt:n,returnUrl:r,signerEmail:i,...a}=e;return{...a,signer:{name:``,email:``,as:e.signer.as},fieldValues:{},personalPurgedAt:t}}async function Pl(e,t,n){let r=new Set(t.filter(e=>e.data.status===`draft`).map(e=>e.id)),i=await e.audit_events.query({where:{envelopeId:{in:t.map(e=>e.id)}},limit:100,...n?{cursor:n}:{}}),a=i.items.filter(e=>!r.has(e.data.envelopeId)&&e.data.personal!==null),o=i.items.filter(e=>r.has(e.data.envelopeId)).map(e=>e.id);return a.length>0&&await e.audit_events.putMany(a.map(e=>({id:e.id,data:xr(e.data)}))),o.length>0&&await e.audit_events.deleteMany(o),i.hasMore?i.cursor:void 0}async function Fl(e,t,n){let r=N(n),i=t.filter(e=>e.data.status!==`draft`),a=i.flatMap(e=>e.data.signerIds),o=a.length>0?await e.signers.getMany(a):new Map,s=a.flatMap(e=>{let t=o.get(e);return t?[{id:e,data:Ml(e,t)}]:[]});s.length>0&&await e.signers.putMany(s),i.length>0&&await e.envelopes.putMany(i.map(e=>({id:e.id,data:Nl(e.data,r)})));let c=t.filter(e=>e.data.status===`draft`).map(e=>e.id);c.length>0&&await e.envelopes.deleteMany(c)}async function Il(e,t){let n=B(e),r={...await e.kv.get(Dl)},i=!1;if(!r.phase||r.phase===`rl`)(await Cn(e.kv,t,3)).more?r.phase=`rl`:Object.assign(r,jl(await e.settings.list(`retention`),t),{phase:`personal`});else if(r.phase===`outbox`){let e=await n.outbox.query({where:{status:{in:[`sent`,`failed`]},nextAttemptAt:{lt:r.p}},limit:100});e.items.length>0&&await n.outbox.deleteMany(e.items.map(e=>e.id)),i=!e.hasMore}else{let e=r.phase===`personal`,i=e?r.p:r.r,a=await n.envelopes.query({where:{createdAt:{gte:(e?r.pf:r.rf)??``,lt:N(i)}},limit:10,...r.cursor?{cursor:r.cursor}:{}}),o=t=>e?t.personalPurgedAt:t.recordsPurgedAt,s=a.items.filter(({data:e})=>!o(e)&&(kl(e)??i)<i),c=s.length===0;if(!r.step&&s.length>0){if(e)r.acursor=await Pl(n,s,r.acursor);else{let e=await n.audit_events.query({where:{envelopeId:{in:s.map(e=>e.id)}},limit:100});if(e.items.length>0&&await n.audit_events.deleteMany(e.items.map(e=>e.id)),e.hasMore)r.acursor=`more`;else{delete r.acursor;let e=s.flatMap(e=>e.data.pdf?.ids??[]),t=s.flatMap(e=>e.data.snapshot?.ids??[]);e.length>0&&await n.artifacts.deleteMany(e),t.length>0&&await n.snapshots.deleteMany(t)}}r.acursor||(r.step=1)}else if(s.length>0){if(e)await Fl(n,s,t);else{let e=s.flatMap(e=>e.data.signerIds);e.length>0&&await n.signers.deleteMany(e);let r=N(t);await n.envelopes.putMany(s.map(({id:e,data:t})=>({id:e,data:{...t,title:``,signerIds:[],snapshot:null,pdf:null,pdfSha256:null,recordsPurgedAt:r}})))}c=!0}if(c){delete r.step;for(let{data:e}of a.items)!o(e)&&!s.some(t=>t.data===e)&&(!r.keep||e.createdAt<r.keep)&&(r.keep=e.createdAt);a.hasMore&&a.cursor?r.cursor=a.cursor:(r[e?`pf`:`rf`]=r.keep??N(i),delete r.cursor,delete r.keep,r.phase=e?`records`:`outbox`)}}return i&&delete r.phase,await e.kv.set(Dl,r),i||await e.cron?.schedule(El,{schedule:N(t)}),i}async function Ll(e,t,n=Date.now()){return e.name!==Tl&&e.name!==El?!1:(await Il(t,n),!0)}const Rl=e=>Ol(e)||e.status===`completed`&&!e.pdfSha256;async function zl(e,t){let n=B(e),r;if(t.includes(`@`)){let e=t.toLowerCase(),[i,a]=await Promise.all([n.signers.query({where:{email:e},limit:10}),n.envelopes.query({where:{signerEmail:e},limit:10})]),o=new Map(a.items.map(e=>[e.id,e.data])),s=[...new Set(i.items.map(e=>e.data.envelopeId))].filter(e=>!o.has(e));if(s.length>0)for(let[e,t]of await n.envelopes.getMany(s))o.set(e,t);r=[...o].slice(0,10).map(([e,t])=>({id:e,data:t}))}else{let e=await n.envelopes.get(t);r=e?[{id:t,data:e}]:[]}return{due:r.filter(e=>!Rl(e.data)&&!e.data.personalPurgedAt),open:r.filter(e=>Rl(e.data)).length}}async function Bl(e,t,n){let r=B(e),i=await Pl(r,t.due);if(i&&=await Pl(r,t.due,i),i)throw Error(`audit trail too long for one request`);await Fl(r,t.due,n),await r.outbox.deleteMany(t.due.flatMap(e=>[`complete-${e.id}`,...e.data.signerIds.map(e=>`invite-${e}`)]))}const Vl=new Set([`localhost`,`127.0.0.1`,`[::1]`]);function Hl(e=T){return E(e(32))}const Ul=e=>ml(e)===null;function Wl(e){let t=[];for(let n of e.split(/\r?\n/)){let e=n.trim();if(e===``)continue;let r;try{r=new URL(e)}catch{return{ok:!1,entry:e}}if(!(r.protocol===`https:`||r.protocol===`http:`&&Vl.has(r.hostname))||r.username||r.password||e.includes(`#`)||e.includes(`?`))return{ok:!1,entry:e};t.push(r.href)}return t.length>10?{ok:!1,entry:`too many entries`}:{ok:!0,entries:t}}async function Gl(e,t,n){let r=ml(t.masterKey);if(!r)return{ok:!1,code:`MASTER_KEY_MISSING`};let i=t.name.trim();if(i===``||i.length>100)return{ok:!1,code:`NAME_REQUIRED`};let a=Rt(n.random),o={name:i,clientId:a,createdAt:n.now,lastUsedAt:null,revokedAt:null,returnUrlAllowlist:t.returnUrlAllowlist};return await e.put(a,o),{ok:!0,client:o,pairing:It(a,await Lt(r,a))}}async function Kl(e,t,n){return(await e.updateIf(t,{where:{revokedAt:null},set:{revokedAt:n}})).applied}async function ql(e){return(await e.query({orderBy:{createdAt:`desc`},limit:100})).items.map(e=>e.data)}function Jl(e){let t=(e??``).split(`,`).filter(e=>e.trim()!==``).length;return t===0?{state:`missing`,canSaveSecrets:!1,keyCount:0,banner:{tone:`error`,message:`EMDASH_ENCRYPTION_KEY is not set, so secret settings (the integration master key and the Turnstile secret) cannot be saved. Set it in the site environment and restart.`}}:{state:`ready`,canSaveSecrets:!0,keyCount:t,banner:null}}function Yl(e){let t=`PLUGIN_SETTING_ENCRYPTION_KEY_MISSING`,n=e=>e.includes(t)||e.includes(`PluginSettingEncryptionError`);return typeof e==`string`?n(e):e instanceof Error?n(e.message)||e.name===`PluginSettingEncryptionError`:typeof e==`object`&&e?e.code===t:!1}const Xl=e=>e.storage.templates,Zl=e=>({...oe(`BAD_REQUEST`).body,...e?{issues:e}:{}}),Ql=()=>oe(`TEMPLATE_NOT_FOUND`).body;function $l(e){let t=V(e).id;return typeof t==`string`&&t.length>0&&t.length<=200&&!t.includes(`:`)?t:null}const eu=(e,t)=>({id:e,...t}),tu=(e,{body:t,...n})=>({id:e,...n});async function nu(e,t){let n=await Xl(e).get(t);return n&&n.status!==`version`?n:null}const ru={"templates/create":{handler:(async(e,t)=>{let n=crypto.randomUUID(),r=jr(e.input,{id:n,now:N()});if(!r.ok)return Zl(r.error);let{head:i,versions:a}=r.value;return await Xl(t).putMany([{id:n,data:i},...a]),{ok:!0,template:eu(n,i)}})},"templates/update":{handler:(async(e,t)=>{let n=$l(e.input);if(!n)return Zl();let r=await nu(t,n);if(!r)return Ql();let i=Mr(r,e.input,{id:n,now:N()});return i.ok?(await Xl(t).putMany([{id:n,data:i.value.head},i.value.version]),{ok:!0,template:eu(n,i.value.head)}):Zl(i.error)})},"templates/get":{handler:(async(e,t)=>{let n=$l(e.input);if(!n)return Zl();let r=V(e.input).version;if(r!==void 0&&!(Number.isSafeInteger(r)&&r>=1))return Zl();let i=r,a=await Xl(t).getMany(i===void 0?[n]:[n,z(n,i)]),o=a.get(n);if(!o||o.status===`version`)return Ql();let s=i===void 0?o:a.get(z(n,i));if(!s)return Ql();let c=Array.from({length:o.version},(e,t)=>t+1);return{ok:!0,template:eu(n,{...s,status:o.status}),versions:c}})},"templates/list":{handler:(async(e,t)=>{let n=V(e.input).status??`active`;if(n!==`active`&&n!==`archived`)return Zl();let{items:r}=await Xl(t).query({where:{status:n},limit:200});return{ok:!0,templates:r.map(e=>tu(e.id,e.data)).sort((e,t)=>e.name<t.name?-1:e.name>t.name?1:0)}})},"templates/archive":{handler:(async(e,t)=>{let n=$l(e.input);if(!n)return Zl();let r=await nu(t,n);if(!r)return Ql();if(r.status===`archived`)return{ok:!0,template:eu(n,r)};let i=Nr(r,N());return await Xl(t).putMany([{id:n,data:i}]),{ok:!0,template:eu(n,i)}})}},iu=(e,t)=>({severity:`error`,title:e,...t?{message:t}:{}}),au=e=>B(e.ctx).clients;async function ou(e){return(await e.ctx.settings.list()).find(e=>e.key===`integrationMasterKey`)?.value}const su=e=>typeof e==`string`&&e.trim()!==``;function cu(e,t,n=[]){let r=ml(e)!==null,o=typeof e==`object`&&!!e,s=Jl(null).banner;return J([i(`Integrations`),...h([o&&s&&{severity:`error`,title:`Encryption key missing`,message:s.message},!r&&!o&&{severity:`warning`,title:su(e)?`Integration master key is too short`:`Integration master key not set`,message:`Clients are paired with secrets derived from the master key. Generate one here, or save one of at least 32 characters in Settings.`}]),...n,...r||o||su(e)?[]:[g([_(`integrations.generate-key`,`Generate master key`,{style:`primary`})])],i(`Clients`),l({columns:[c(`name`,`Name`),c(`clientId`,`Client id`),c(`created`,`Created`,`relative_time`),c(`status`,`Status`,`badge`),c(`revoke`,``,`element`)],rows:t.map(e=>({name:e.name,clientId:e.clientId,created:e.createdAt,status:e.revokedAt?`Revoked`:`Active`,...e.revokedAt?{}:{revoke:_(`client.revoke`,`Revoke`,{style:`danger`,value:e.clientId,confirm:{title:`Revoke this client?`,text:`Its intents and receipts are refused from now on. This cannot be undone; create a new client to pair again.`,confirm:`Revoke client`,deny:`Keep`,style:`danger`}})}})),pageActionId:`clients.page`,emptyText:`No clients yet.`}),i(`Add a client`),a(`The pairing string is shown once, right after you create the client, and cannot be shown again. Paste it into the other plugin's settings. Return URLs: one per line, https (http only for localhost); leave blank to allow this site only.`),w({fields:[y(`name`,`Name`,{initialValue:``}),y(`returnUrlAllowlist`,`Allowed return URLs`,{multiline:!0,initialValue:``})],submit:{label:`Create client`,actionId:`client.create`}})])}async function lu(e,t,n=[]){return cu(t,await ql(au(e)),n)}async function uu(e){let[t,n]=await Promise.all([ou(e),ql(au(e))]);return cu(t,n)}async function du(e){let t=await ou(e);if(su(t))return lu(e,t,h([iu(`Key already set`,`Changing it would re-pair every client.`)]));let n=Hl();try{await e.ctx.settings.set(`integrationMasterKey`,n)}catch(n){if(!Yl(n))throw n;return lu(e,t,h([iu(`Encryption key missing`,Jl(null).banner?.message)]))}return lu(e,n,h([{severity:`info`,title:`Master key generated`}]))}async function fu(e,t){let n=await ou(e),r=(e,t)=>typeof e==`string`?e.slice(0,t):``,i=Wl(r(t.returnUrlAllowlist,2e3));if(!i.ok)return lu(e,n,h([iu(`Not created`,`Return URL not allowed: ${i.entry.slice(0,200)}`)]));let a=await Gl(au(e),{name:r(t.name,200),returnUrlAllowlist:i.entries,masterKey:n},{now:N(e.now)});return a.ok?lu(e,n,[...h([{severity:`warning`,title:`Copy the pairing string now`,message:`It is shown only this once and cannot be recovered. Treat it like a password.`}]),d({code:a.pairing})]):lu(e,n,h([iu(`Not created`,a.code===`MASTER_KEY_MISSING`?`Set the integration master key first (at least 32 characters), or generate one.`:`Give the client a name of up to 100 characters.`)]))}async function pu(e,t){let n=await Kl(au(e),t,N(e.now));return lu(e,await ou(e),h([n?{severity:`info`,title:`Client revoked`}:iu(`Not revoked`,`Unknown or already revoked.`)]))}const J=e=>({blocks:e}),Y=(e,t=200)=>typeof e==`string`?e.trim().slice(0,t):``,X=(e,t,n)=>t.handler({input:n,user:e.user??null},e.ctx),mu=e=>Aa[e],hu=e=>ru[e],gu={INVALID_NAME:`Give the template a name of up to 200 characters.`,INVALID_BODY:`The template text is required (up to 100,000 characters).`,INVALID_DESCRIPTION:`The description is too long (up to 1,000 characters).`,TEMPLATE_ARCHIVED:`This template is archived.`,INVALID_INTEGRATIONS:`Choose whether integrations may use the template.`,INVALID_TITLE:`The title is too long or has control characters.`,INVALID_SIGNER_NAME:`Enter the signer's name.`,INVALID_SIGNER_EMAIL:`Enter a valid email address for the signer.`,INVALID_FIELDS:`A field value is too long or not text.`,MISSING_FIELD:`A template field has no value.`,DOCUMENT_TOO_LARGE:`The document is too long to sign (up to 131,072 characters and 1,500 lines).`};function _u(e,t=`The change was refused.`){let n=Array.isArray(e.issues)?e.issues:[];return n.length>0?n.map(e=>gu[e.code??``]??`${e.path??`input`} (${e.code??`invalid`})`).join(` `):e.error?.message??t}const vu=(e,t,n)=>({severity:e,title:t,...n?{message:n}:{}}),Z=(e,t)=>vu(`error`,e,t),yu=(e,t)=>vu(`warning`,e,t),bu=(e,t)=>_(e,t,{style:`secondary`}),Q=(e,t)=>vu(`info`,e,t),xu=()=>bu(`envelopes.back`,`Back to envelopes`),Su=()=>bu(`templates.back`,`Back to templates`),Cu=e=>_(`envelope.open`,`Open envelope`,{value:e}),wu={"envelope.created":`Envelope created`,"envelope.sent":`Envelope sent`,"signer.viewed":`Signer opened the document`,"signer.consented":`Signer gave consent`,"signer.signed":`Signer signed`,"signer.declined":`Signer declined`,"envelope.completed":`Envelope completed`,"envelope.declined":`Envelope declined`,"envelope.voided":`Envelope voided`,"envelope.expired":`Envelope expired`},Tu=e=>!L(e.ctx)&&yu(`Set the site URL`,nr);async function Eu(e){let t=await or(e.ctx);return[Tu(e),t.state===`no_transport`&&yu(`No email transport`,`No email provider is configured, so signing invitations stay queued and are not delivered. Install an email provider plugin.`),t.failed>0&&yu(`${t.failed} email${t.failed===1?``:`s`} could not be delivered`,`Open the envelope and use Resend invitation if a signer never received theirs.`)]}async function Du(e,t,n=[],r){let o=Er(t)?t:``,[s,u]=await Promise.all([X(e,mu(`envelopes/list`),{...o?{status:o}:{},...r?{cursor:r}:{}}),Eu(e)]),d=typeof s.nextCursor==`string`?s.nextCursor:void 0,f=(s.envelopes??[]).map(e=>{let t=e.signer;return{title:e.title,signer:t?`${t.name??``} <${t.email??``}>`:``,status:e.status,created:e.createdAt,open:_(`envelope.open`,`Open`,{value:e.id})}});return J([i(`Envelopes`),...h(u),...n,w({fields:[x(`status`,`Status`,[{label:`Any status`,value:``},...Cr.map(e=>({label:e.replaceAll(`_`,` `),value:e}))],{initialValue:o})],submit:{label:`Filter`,actionId:`envelopes.filter`}}),a(`Newest first, 100 a page. Create an envelope from a template on the Templates page.`),l({columns:[c(`title`,`Title`),c(`signer`,`Signer`),c(`status`,`Status`,`badge`),c(`created`,`Created`,`relative_time`),c(`open`,``,`element`)],rows:f,pageActionId:`envelopes.page:${o}`,...d?{nextCursor:d}:{},emptyText:`No envelopes match.`}),i(Ou),w({fields:[y(`subject`,`Signer email or envelope id`)],submit:{label:`Find`,actionId:`retention.preview`}})])}const Ou=`Delete personal data`;async function ku(e,t,n){let r=await zl(e.ctx,t),a=r.due.length;return n&&a>0&&await Bl(e.ctx,r,e.now),J([i(Ou),...h([{severity:n?`info`:`warning`,title:n&&a>0?`Personal data deleted`:a+r.open>0?`${a} envelope(s) to delete, ${r.open} kept for now`:`No envelopes found`,message:`Signed records stay for their own period; open envelopes and pending PDFs are skipped.`}]),g([...!n&&a>0?[_(`retention.erase`,Ou,{style:`danger`,value:t,confirm:{title:`${Ou}?`,text:`This cannot be undone.`,confirm:`Delete`,deny:`Keep`,style:`danger`}})]:[],xu()])])}async function Au(e,t){if(!t)return`missing`;let n=await B(e.ctx).outbox.get(`invite-${t}`);return n?n.status===`failed`?`failed`:`queued`:`missing`}async function ju(e,t,n={}){let{envelopes:r,signers:s,audit_events:u}=B(e.ctx),d=n.envelope??await r.get(t);if(!d)return J([i(`Envelope`),...h([Z(`Envelope not found`,`It may have been removed.`)]),g([xu()])]);let f=d.status===`sent`||d.status===`in_progress`,[p,m,y]=await Promise.all([u.query({where:{envelopeId:t},orderBy:{seq:`asc`},limit:200}),n.signers?Promise.resolve(n.signers):d.signerIds.length>0?s.getMany(d.signerIds).then(e=>[...e].map(([e,t])=>({id:e,name:t.name,email:t.email,status:t.status}))):Promise.resolve([]),n.invite??(d.status===`sent`?Au(e,d.signerIds[0]):Promise.resolve(`n/a`))]),b=m[0],x=d.status===`sent`&&(y===`missing`||y===`failed`),S=null;if(d.status===`completed`&&!d.recordsPurgedAt)if(d.pdfSha256){let n=await ca(e.ctx,t,e.now);S=g([v(`Download signed PDF`,{kind:`external`,url:`${e.origin}${n.url}`},{appearance:`primary`})])}else S=a(`The signed PDF is still being prepared. Reload in a minute.`);let C=[d.status===`draft`&&_(`envelope.send`,`Send for signature`,{style:`primary`,value:t}),x&&_(`envelope.resend`,`Resend invitation`,{style:`primary`,value:t}),(d.status===`draft`||f)&&_(`envelope.void`,`Void`,{style:`danger`,value:t,confirm:{title:`Void this envelope?`,text:`The signer will no longer be able to sign it. This cannot be undone.`,confirm:`Void envelope`,deny:`Keep`,style:`danger`}}),xu()].filter(e=>e!==!1);return J([i(d.title),...h([x&&{severity:`warning`,title:`The invitation was not delivered`,message:y===`failed`?`The email gave up after repeated failures. Resend invitation queues a fresh email with a new signing link.`:`The invitation was never queued. Resend invitation queues it with a new signing link.`},x&&Tu(e)]),...n.extra??[],...d.personalPurgedAt?[a(`Personal data deleted ${d.personalPurgedAt}${d.recordsPurgedAt?`; signed records deleted`:``} (retention).`)]:[],o([{label:`Status`,value:d.status.replaceAll(`_`,` `)},{label:`Template`,value:`${d.templateId} v${d.templateVersion}`},{label:`Signer`,value:b?`${b.name} <${b.email}>`:d.signer.email},{label:`Signer status`,value:b?.status??`not sent yet`},{label:`Delivery`,value:d.delivery},{label:`Created`,value:d.createdAt},{label:`Sent`,value:d.sentAt??`Not sent`},{label:`Expires`,value:d.expiresAt??`Not set`},{label:`Completed`,value:d.completedAt??`Not completed`},{label:`Document SHA-256`,value:d.docSha256??`Set when sent`},{label:`Final hash`,value:d.finalHash??`Set when completed`}]),...S?[S]:[],g(C),i(`Audit timeline`),l({columns:[c(`seq`,`#`,`number`),c(`event`,`Event`),c(`at`,`When`,`text`),c(`actor`,`By`)],rows:p.items.map(({data:e})=>({seq:e.seq,event:wu[e.type]??e.type,at:e.at,actor:e.actor})),pageActionId:`audit.page:${t}`,emptyText:`No events yet.`})])}async function Mu(e,t){let n;try{n=await X(e,mu(`envelopes/send`),{id:t})}catch{return J([i(`Envelope`),...h([Z(`The envelope was sent but the invitation could not be queued`,`Open the envelope and use Resend invitation.`)]),g([Cu(t)])])}if(n.ok!==!0)return J([i(`Envelope`),...h([Z(`Not sent`,_u(n))]),g([Cu(t),xu()])]);let r=n.invitation===`SITE_URL_MISSING`;return J([i(`Envelope`),...h([r?{severity:`warning`,title:`Envelope sent, but no invitation was queued`,message:nr}:Q(`Envelope sent`,`The signer's invitation is queued.`)]),g([Cu(t),xu()])])}async function Nu(e,t){let n=await X(e,mu(`envelopes/void`),{id:t});if(n.ok!==!0){let r=n.error?.code===`ENVELOPE_CLOSED`;return ju(e,t,{extra:h([Z(r?`This envelope cannot be voided`:`Not voided`,r?`It is already completed, declined, voided or expired.`:_u(n))])})}return ju(e,t,{envelope:n.envelope,invite:`n/a`,extra:h([Q(`Voided`,`The signer can no longer sign this envelope.`)])})}async function Pu(e,t){let n=await X(e,mu(`envelopes/resend`),{id:t});return n.ok===!0?ju(e,t,{envelope:n.envelope,invite:`queued`,signers:n.signers,extra:h([Q(`Invitation queued`,`A new email with a new signing link is on its way.`)])}):ju(e,t,{extra:h([n.error?.code===`INVITATION_QUEUED`?Q(`Already queued`,`The invitation is queued or was sent.`):Z(`Not resent`,_u(n,`Only an envelope that is sent and unsigned can be resent.`))])})}const Fu=/^(signer|participant)\./;async function Iu(e,t,n=[]){let r=await X(e,hu(`templates/get`),{id:t}),o=r.template;return r.ok!==!0||!o?J([i(`New envelope`),...h([Z(`Template not found`)]),...n]):J([i(`New envelope: ${o.name}`),...n,a(`Creates a draft you can check before sending it for signature. Signer fields: one per line as key: Label, ending in * when required.`),w({fields:[y(`title`,`Title`,{initialValue:o.name}),y(`signerName`,`Signer name`),y(`signerEmail`,`Signer email`),...o.fields.filter(e=>!Fu.test(e)).map(e=>y(`field:${e}`,e)),y(`signerFields`,`Fields the signer fills in (optional)`,{multiline:!0,placeholder:`phone: Phone number *`})],submit:{label:`Create draft`,actionId:`envelope.create`},blockId:`envelope-new:${t}`}),g([Su()])])}function Lu(e){return typeof e==`string`?e.slice(0,4e3).split(`
53
- `).map(e=>e.trim()).filter(e=>e!==``).map(e=>{let t=e.indexOf(`:`),n=(t===-1?e:e.slice(0,t)).trim(),r=t===-1?``:e.slice(t+1).trim(),i=r.endsWith(`*`);return i&&(r=r.slice(0,-1).trim()),{key:n,label:r,...i?{required:!0}:{}}}):[]}async function Ru(e,t,n){let r=t?.startsWith(`envelope-new:`)?t.slice(13):``;if(!r)return J(h([Z(`Choose a template first`)]));let i={};for(let[e,t]of Object.entries(n))e.startsWith(`field:`)&&(i[e.slice(6)]=typeof t==`string`?t:``);let a=Y(n.title),o=Lu(n.signerFields),s=await X(e,mu(`envelopes/create`),{templateId:r,...a?{title:a}:{},signer:{name:Y(n.signerName),email:Y(n.signerEmail)},fields:i,...o.length>0?{signerFields:o}:{}});if(s.ok!==!0)return Iu(e,r,h([Z(`Not saved`,_u(s))]));let c=s.envelope.id;return ju(e,c,{extra:h([Q(`Draft created`,`Check the details, then send it.`)])})}async function zu(e,t=[]){let n=((await X(e,hu(`templates/list`),{})).templates??[]).map(e=>({name:e.name,version:e.version,fields:(e.fields??[]).join(`, `),integrations:e.integrations===!0?`Yes`:`No`,updated:e.updatedAt,edit:_(`template.edit`,`Edit`,{value:e.id}),use:_(`envelope.new`,`New envelope`,{style:`primary`,value:e.id})}));return J([i(`Templates`),...t,l({columns:[c(`name`,`Name`),c(`version`,`Version`,`number`),c(`fields`,`Fields`),c(`integrations`,`Integrations`),c(`updated`,`Updated`,`relative_time`),c(`edit`,``,`element`),c(`use`,``,`element`)],rows:n,pageActionId:`templates.page`,emptyText:`No templates yet. Add one below.`}),i(`New template`),a(`Write the document in Markdown. Use {{field}} for values filled in per envelope, and {{signer.name}} for the signer.`),w({fields:[y(`name`,`Name`),y(`description`,`Description (optional)`),y(`body`,`Template text`,{multiline:!0}),Bu(!1)],submit:{label:`Create template`,actionId:`template.create`}})])}function Bu(e){return S(`integrations`,`Available to integrations`,{description:`Paired sites (such as Events) may send this template for signing.`,initialValue:e})}function Vu(e){let t=Object.fromEntries(In(e).map(e=>[e,`«${e}»`]));try{return Ln(e,t)}catch{return e}}function Hu(e,t,n=[]){let r=String(t.body??``),o=In(r);return J([i(`Edit template: ${String(t.name??``)}`),...n,a(`Version ${String(t.version??1)}. Saving writes a new version; sent envelopes keep the text they were sent with.`),w({fields:[y(`name`,`Name`,{initialValue:String(t.name??``)}),y(`description`,`Description (optional)`,{initialValue:String(t.description??``)}),y(`body`,`Template text`,{initialValue:r,multiline:!0}),Bu(t.integrations===!0)],submit:{label:`Save new version`,actionId:`template.save`},blockId:`template:${e}`}),i(`Preview`),a(o.length>0?`Fields: ${o.join(`, `)}. Placeholders show as «name».`:`This template has no fields.`),d({code:Vu(r)}),g([_(`envelope.new`,`New envelope from this template`,{style:`primary`,value:e}),_(`template.archive`,`Archive`,{style:`danger`,value:e,confirm:{title:`Archive this template?`,text:`It can no longer be used for new envelopes. Sent envelopes are not affected.`,confirm:`Archive`,deny:`Keep`,style:`danger`}}),Su()])])}async function Uu(e,t,n=[]){let r=await X(e,hu(`templates/get`),{id:t});return r.ok!==!0||!r.template?zu(e,h([Z(`Template not found`)])):Hu(t,r.template,n)}async function Wu(e,t){let n=await X(e,hu(`templates/create`),{name:Y(t.name),body:typeof t.body==`string`?t.body:``,...Y(t.description,1e3)?{description:Y(t.description,1e3)}:{},integrations:t.integrations===!0});return n.ok===!0?zu(e,h([Q(`Template created`)])):zu(e,h([Z(`Not saved`,_u(n))]))}async function Gu(e,t,n){let r=t?.startsWith(`template:`)?t.slice(9):``;if(!r)return J(h([Z(`Choose a template first`)]));let i={name:Y(n.name),body:typeof n.body==`string`?n.body:``,description:Y(n.description,1e3),integrations:n.integrations===!0},a=await X(e,hu(`templates/update`),{id:r,...i});return a.ok===!0?Hu(r,a.template,h([Q(`Saved`)])):Hu(r,{...i,version:`?`},h([Z(`Not saved`,_u(a))]))}async function Ku(e,t){let n=await X(e,hu(`templates/archive`),{id:t});return zu(e,h([n.ok===!0?Q(`Template archived`):Z(`Not archived`,_u(n))]))}const qu=[{key:`senderName`,label:`Sender name`,kind:`text`},{key:`expiryDays`,label:`Envelope expiry (days)`,kind:`number`,min:1,max:365},{key:`consentVersion`,label:`Consent version`,kind:`text`},{key:`consentWording`,label:`Consent wording`,kind:`long`},{key:`retentionPersonalDataMonths`,label:`Keep personal data (months)`,kind:`number`,min:1,max:120},{key:`retentionSignedRecordsYears`,label:`Keep signed records (years)`,kind:`number`,min:1,max:50},{key:`turnstileSiteKey`,label:`Turnstile site key`,kind:`text`}],Ju=[{key:`turnstileSecretKey`,label:`Turnstile secret key`},{key:`integrationMasterKey`,label:`Integration master key`}],Yu=e=>typeof e==`string`&&e!==``?`readable`:typeof e==`object`&&e?`unreadable`:`unset`;function Xu(e,t,n=[]){let r=Ju.some(e=>t[e.key]===`unreadable`),o=Jl(null).banner;return J([i(`Settings`),...h([r&&o&&{severity:`error`,title:`Encryption key missing`,message:o.message},t.integrationMasterKey===`unset`&&yu(`Integration master key not set`,`Other plugins cannot create envelopes through the integration protocol until it is saved.`)]),...n,w({fields:[...qu.map(t=>t.kind===`number`?b(t.key,t.label,{min:t.min,max:t.max,...typeof e[t.key]==`number`?{initialValue:e[t.key]}:{}}):y(t.key,t.label,{multiline:t.kind===`long`,initialValue:typeof e[t.key]==`string`?e[t.key]:``})),...Ju.map(e=>C(e.key,`${e.label} (leave blank to keep)`,{hasValue:t[e.key]===`readable`}))],submit:{label:`Save settings`,actionId:`settings.save`}}),a(`Reminder and one-time-code settings (Pro) are in the plugin's own settings panel.`)])}async function Zu(e){let t=await e.ctx.settings.list(),n=Object.fromEntries(t.map(e=>[e.key,e.value]));return{values:n,secrets:Object.fromEntries(Ju.map(e=>[e.key,Yu(n[e.key])]))}}async function Qu(e){let{values:t,secrets:n}=await Zu(e);return Xu(t,n)}async function $u(e,t){let{values:n,secrets:r}=await Zu(e),i=[],a=[];for(let e of qu){let r=t[e.key];if(r==null||r===``)continue;let o;if(e.kind===`number`){if(o=Number(r),!Number.isInteger(o)||o<(e.min??0)||o>(e.max??2**53-1)){a.push(`${e.label} must be a whole number from ${e.min} to ${e.max}.`);continue}}else o=Y(r,e.kind===`long`?2e3:200);o!==n[e.key]&&i.push([e.key,o])}let o=Ju.filter(e=>Y(t[e.key],500)!==``);if(o.some(e=>e.key===`integrationMasterKey`&&Ul(Y(t[e.key],500)))&&a.push(`The integration master key must be at least 32 characters, or use Generate on the Integrations page.`),a.length>0)return Xu(n,r,h([Z(`Not saved`,a.join(` `))]));if(i.length+o.length>6)return Xu(n,r,h([Z(`Too many changes at once`,`Save at most 6 settings at a time.`)]));if(i.length+o.length===0)return Xu(n,r,h([Q(`Nothing to save`)]));let s={...n},c={...r};try{for(let n of o)await e.ctx.settings.set(n.key,Y(t[n.key],500)),c[n.key]=`readable`;for(let[t,n]of i)await e.ctx.settings.set(t,n),s[t]=n}catch(e){if(!Yl(e))throw e;let t=Jl(null).banner;return Xu(n,r,h([{severity:`error`,title:`Encryption key missing`,message:t?.message}]))}return Xu(s,c,h([Q(`Saved`)]))}const ed=e=>Y(e,200);async function td(e,t){if(t.type===`page_load`)switch(t.page){case`/envelopes`:return Du(e,``);case`/templates`:return zu(e);case`/settings`:return Qu(e);case`/integrations`:return uu(e);default:return J(h([Z(`Page not found`)]))}if(t.type===`form_submit`){let n=t.values;switch(t.action_id){case`envelopes.filter`:return Du(e,Y(n.status));case`envelope.create`:return Ru(e,t.block_id,n);case`template.create`:return Wu(e,n);case`template.save`:return Gu(e,t.block_id,n);case`settings.save`:return $u(e,n);case`client.create`:return fu(e,n);case`retention.preview`:return ku(e,Y(n.subject),!1)}}else{let n=ed(t.value);if(t.action_id.startsWith(`envelopes.page:`))return Du(e,t.action_id.slice(15),[],Y(t.value,500)||void 0);if(t.action_id.startsWith(`audit.page:`))return ju(e,ed(t.action_id.slice(11)));switch(t.action_id){case`envelopes.back`:case`envelopes.page`:return Du(e,``);case`envelope.open`:return ju(e,n);case`envelope.send`:return Mu(e,n);case`envelope.void`:return Nu(e,n);case`envelope.resend`:return Pu(e,n);case`retention.erase`:return ku(e,n,!0);case`envelope.new`:return Iu(e,n);case`integrations.generate-key`:return du(e);case`client.revoke`:return pu(e,n);case`clients.page`:return uu(e);case`templates.back`:case`templates.page`:return zu(e);case`template.edit`:return Uu(e,n);case`template.archive`:return Ku(e,n)}}return J(h([Z(`Unknown action`)]))}const nd={admin:{handler:(async(e,t)=>{let n=`http://localhost`;try{n=new URL(e.request?.url??``).origin}catch{}return td({ctx:t,origin:n,now:Date.now(),user:e.user??null},e.input)})}},rd=[`completed`,`declined`,`voided`,`expired`],id=e=>{if(!e)return;let t=Date.parse(e);return Number.isNaN(t)?void 0:Math.floor(t/1e3)};function ad(e,t){let{status:n,clientId:r,externalRef:i}=t;if(!rd.includes(n)||!r||!i||t.docSha256===null)return;let a=n===`completed`,o=a?id(t.completedAt):id(t.closedAt)??id(t.updatedAt);if(o===void 0)return;let s={v:1,typ:`receipt`,cid:r,envelopeId:e,ref:i,status:n,docSha256:t.docSha256,pdfSha256:a?t.pdfSha256??null:null,finalHash:a?t.finalHash:null,at:o};return Ye(`receipt`,s).ok?s:void 0}async function od(e,t,n){let r=ad(e,t);return r?dt(`receipt`,r,n):void 0}function sd(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`):void 0}function cd(e){let t={};return{settings:()=>t,async getClient(n){let[r,i]=await Promise.all([e.settings.list(),B(e).clients.get(n)]);t=Object.fromEntries(r.map(e=>[e.key,e.value]));let a=ml(t.integrationMasterKey);if(!(!a||!i))return{secret:await Lt(a,n),revoked:i.revokedAt!==void 0&&i.revokedAt!==null,returnUrlAllowlist:sd(i.returnUrlAllowlist)}}}}async function ld(e,t,n){let r=ml(n);if(!(!r||!t.clientId))return od(e,t,await Lt(r,t.clientId))}async function ud(e,t,n=Date.now()){let r=await ut({token:V(e).request,now:n,getClient:cd(t).getClient});if(!r.ok)return U(r.error);let i=[],a;for(let e=0;e<3;e++){let e=await B(t).templates.query({where:{status:`active`},limit:200,...a===void 0?{}:{cursor:a}});if(i.push(...e.items),!e.hasMore||!e.cursor)break;a=e.cursor}return{ok:!0,templates:i.filter(e=>Pr(e.data)).map(e=>({id:e.id,name:e.data.name,version:e.data.version})).sort((e,t)=>e.name<t.name?-1:e.name>t.name?1:e.id<t.id?-1:1)}}const dd=(e,t)=>ud(e.input,t),fd=[`sent`,`in_progress`];function pd(e){let t=V(e).token;return typeof t==`string`&&t.length>0&&t.length<=200?t:null}const md=e=>({...e.requestMeta?.ip?{ip:e.requestMeta.ip}:{},...e.requestMeta?.userAgent?{ua:e.requestMeta.userAgent}:{}});function hd(e){try{return e!==void 0&&new URL(e.url).searchParams.has(`token`)}catch{return!1}}function gd(e,t){let n=new Map,r,i={get:t=>{let r=n.get(t);return r||(r=e.kv.get(t),n.set(t,r)),r},set:async(e,t)=>{r={key:e,value:t}}},a=Date.now(),o=()=>Sn(i,t.requestMeta?.ip??`unknown`,a,{scope:`ceremony`,limit:20,windowSeconds:600,salt:`esign-ceremony/1`});return{async blocked(){return!(await o()).ok},async fail(){let t=await o();return t.ok&&r&&await e.kv.set(r.key,r.value),U(t.ok?`SIGNING_TOKEN_INVALID`:`RATE_LIMITED`)}}}async function _d(e,t){let{items:n}=await B(e).signers.query({where:{tokenHash:await j(t)},limit:1}),r=n[0];return r&&await he(t,r.data.tokenHash)?r:null}async function vd(e,t){let{items:n}=await B(e).signers.query({where:{copyTokenHash:await j(t)},limit:1}),r=n[0];return r?.data.copyTokenHash&&await he(t,r.data.copyTokenHash)?r:null}const yd=e=>!!(e.returnUrl&&e.clientId),bd=(e,t)=>yd(t)?e.settings.get(`integrationMasterKey`):Promise.resolve(void 0);async function xd(e,t,n){if(!t.returnUrl)return{};let r=await ld(e,t,n);return{returnUrl:t.returnUrl,...r?{receipt:r}:{}}}const Sd=(e,t)=>e.find(e=>e.key===t)?.value;async function Cd(e,t){let n=await(t?e.settings.list():e.settings.list(`consent`)),r=(e,t)=>{let r=Sd(n,e);return typeof r==`string`&&r.length>0?r:t},i=r(`consentWording`,`I agree to use electronic records and an electronic signature for this document.`);return{version:r(`consentVersion`,`1`),wording:i,sha256:await F(i),masterKey:Sd(n,`integrationMasterKey`)}}const wd=(e,t)=>e.expiresAt!==null&&e.expiresAt<=t,Td=(e,t)=>e.signerIds.length>1?t.order:void 0;async function Ed(e,t,n,r,i){let a=B(e).audit_events,o=i;for(let e=0;e<2;e++){if(o??=await hr(t,await _r(a,t),r,n),await vr(a,o))return o;o=void 0}throw Error(`audit chain contention`)}async function Dd(e,t){if(hd(e.request))return U(`TOKEN_IN_QUERY`);let n=gd(t,e),r=pd(e.input);if(r===null)return n.fail();if(await n.blocked())return U(`RATE_LIMITED`);let i=V(e.input).open===!0,{envelopes:a,snapshots:o}=B(t),s=await _d(t,r),c=s?null:await vd(t,r),l=s??c;if(!l)return n.fail();let u=await a.get(l.data.envelopeId);if(!u)return U(`ENVELOPE_NOT_FOUND`);if(c&&u.status!==`completed`)return n.fail();if(!fd.includes(u.status)||l.data.status!==`pending`){let e={ok:!0,state:`closed`,status:u.status,title:u.title,...c?{}:await xd(l.data.envelopeId,u,await bd(t,u))};return u.status!==`completed`||l.data.status!==`signed`?e:u.pdfSha256?{...e,pdf:`ready`,download:await ca(t,l.data.envelopeId,Date.now())}:{...e,pdf:`pending`}}let d=N();if(wd(u,d))return U(`SIGNING_TOKEN_EXPIRED`);let f=u.document,[p,m]=await Promise.all([u.snapshot?o.getMany(u.snapshot.ids):Promise.resolve(new Map),Cd(t,!1)]),h=f&&!u.snapshot?``:ri([...p.values()]);if(h===null)return U(`INTERNAL`);let g=u.status,_=Td(u,l.data);if(i){let n=!1;if(u.status===`sent`&&(n=(await R(a,l.data.envelopeId,`sent`,`in_progress`,{updatedAt:d})).ok,n&&(g=`in_progress`)),_!==void 0&&(n=(await B(t).signers.updateIf(l.id,{where:{viewedAt:null},set:{viewedAt:d}})).applied),n){let n=Ka(d,u.docSha256??``,md(e),_);if(!(await gr(B(t).audit_events,l.data.envelopeId,n,{salt:u.piiSalt})).ok)throw Error(`audit chain contention`)}}let{participant:v}=l.data;return{ok:!0,state:`ready`,envelope:{id:l.data.envelopeId,title:u.title,status:g,docSha256:u.docSha256,expiresAt:u.expiresAt},signer:{name:l.data.name,as:l.data.as,...v?{participant:v.name}:{}},snapshot:h,...f?{document:{kind:f.kind,name:f.name,bytes:f.bytes,pages:f.pages}}:{},...u.otp?{otp:l.data.otpVerifiedAt?`verified`:`required`}:{},...u.signerFields?.length?{fields:u.signerFields}:{},consent:{version:m.version,wording:m.wording,sha256:m.sha256}}}async function Od(e,t,n){if(hd(e.request))return U(`TOKEN_IN_QUERY`);let r=gd(t,e),i=pd(e.input);if(i===null)return r.fail();let a=Va(e.input);if(!a.ok)return H(a.error);let{envelopes:o,signers:s,audit_events:c}=B(t),l=await _d(t,i);if(!l||l.data.status!==`pending`)return r.fail();let u=l.data.envelopeId,d=await o.get(u);if(!d)return U(`ENVELOPE_NOT_FOUND`);if(d.status===`sent`)return U(`SESSION_REQUIRED`);if(d.status!==`in_progress`||d.document&&!n)return U(`ENVELOPE_CLOSED`);let f=N();if(wd(d,f))return U(`SIGNING_TOKEN_EXPIRED`);if(d.otp&&!l.data.otpVerifiedAt)return U(`OTP_REQUIRED`);if(d.docSha256===null||a.value.docSha256!==d.docSha256)return H([{path:`docSha256`,code:`DOC_CHANGED`}]);let p=await Cd(t,yd(d));if(a.value.consentSha256!==p.sha256)return H([{path:`consentSha256`,code:`CONSENT_CHANGED`}]);let m=d.signerFields??[],h=a.value.fieldValues,g=[...Object.keys(h).filter(e=>!m.some(t=>t.key===e)).map(e=>({path:`fieldValues.${e}`,code:`INVALID_FIELDS`})),...m.filter(e=>e.required&&(h[e.key]??``).trim()===``).map(e=>({path:`fieldValues.${e.key}`,code:`INVALID_FIELDS`}))];if(g.length>0)return H(g);let _=await Ua(d.docSha256,a.value.signature,{fieldValues:h,salt:d.piiSalt}),v=md(e),y={status:`signed`,signature:_,consentAt:f,consentVersion:p.version,consentSha256:p.sha256,signedAt:f,fieldValues:h,...v};if(d.signerIds.length>1)return n?n(t,{envelopeId:u,envelope:d,signer:l,set:y,now:f}):U(`ENVELOPE_CLOSED`);let b=qa({at:f,docSha256:d.docSha256,consentVersion:p.version,consentSha256:p.sha256,signature:_,signerName:l.data.name,who:v}),x=await hr(u,await _r(c,u),b,d.piiSalt),S=await Sr(d.docSha256,x.at(-1)?.data.hash??``),C=await R(o,u,d.status,`completed`,{completedAt:f,finalHash:S,updatedAt:f});if(!C.ok)return U(`ENVELOPE_CLOSED`);if(await s.updateIf(l.id,{where:{status:`pending`},set:y}),!await vr(c,x))throw Error(`audit chain contention`);return await $i(t.cron,u,Date.parse(f)),{ok:!0,status:`completed`,completedAt:f,...await xd(u,C.value,p.masterKey)}}async function kd(e,t){if(hd(e.request))return U(`TOKEN_IN_QUERY`);let n=gd(t,e),r=pd(e.input);if(r===null)return n.fail();let i=Ha(V(e.input).reason);if(i===null)return H([{path:`reason`,code:`INVALID_INPUT`}]);let{envelopes:a,signers:o}=B(t),s=await _d(t,r);if(!s||s.data.status!==`pending`)return n.fail();let c=s.data.envelopeId,l=await a.get(c);if(!l)return U(`ENVELOPE_NOT_FOUND`);if(!Dr(l.status,`declined`))return U(`ENVELOPE_CLOSED`);let u=N();if(wd(l,u))return U(`SIGNING_TOKEN_EXPIRED`);let d=await R(a,c,l.status,`declined`,{closedAt:u,updatedAt:u});if(!d.ok)return U(`ENVELOPE_CLOSED`);let f=md(e);return await o.updateIf(s.id,{where:{status:`pending`},set:{status:`declined`,declinedAt:u,...i===void 0?{}:{declineReason:i},...f}}),await Ed(t,c,l.piiSalt,Ja({at:u,docSha256:l.docSha256,hasReason:i!==void 0,who:f,order:Td(l,s.data)})),{ok:!0,status:`declined`,...await xd(c,d.value,await bd(t,d.value))}}const Ad=e=>(t,n)=>e(t,n),jd=e=>({"public/session":Ad(Dd),"public/submit":Ad((t,n)=>Od(t,n,e)),"public/decline":Ad(kd)}),Md=jd();function Nd(e){try{return new URL(e.site.url).origin}catch{return}}async function Pd(e,t,n={}){let r=(n.now??Date.now)(),i=N(r),{envelopes:a,signers:o,snapshots:s,templates:c,nonces:l}=B(t),u=cd(t),d=await st({token:V(e).intent,now:r,getClient:u.getClient,consumeNonce:async(e,t,n)=>{let r=`${e}.${t}`;try{let t={nonce:r,cid:e,expiresAt:N(n*1e3)};return(await l.compareAndSet(r,null,t)).applied}catch(e){if(ga(e))return!1;throw e}},siteOrigin:Nd(t)});if(!d.ok)return U(d.error);let f=d.value,p=u.settings();if(f.replace===!0)return Rd(t,f,i);let m=f.tplVersion===void 0?void 0:z(f.tpl,f.tplVersion),h=await c.getMany(m===void 0?[f.tpl]:[f.tpl,m]),g=h.get(f.tpl);if(!Pr(g))return U(`TEMPLATE_NOT_FOUND`);let _=qr(g,m===void 0?void 0:h.get(m),f.tplVersion);if(!_.ok)return U(`TEMPLATE_NOT_FOUND`);let v=cr(n.random),y=Qr(f,_.value,{now:i,piiSalt:v});if(!y.ok)return H(y.error);let b={delivery:y.value.delivery,signer:y.value.signer},x=f.resend===!0?(e,n,i)=>rr(t,{signerId:e,envelope:n,token:i,senderSetting:p.senderName,now:r}):void 0,S=A(n.random),C=await j(S),ee=async e=>{let t=await si(f.cid,f.ref,e);return{id:t,sent:await ii(t,y.value,_.value,{now:i,tokenHash:C,expiryDays:ha(p.expiryDays)})}},w=await ee(1);if(!w.sent.ok)return Array.isArray(w.sent.error)?H(w.sent.error):U(`INTERNAL`);let T=await a.compareAndSet(w.id,null,w.sent.value.envelope);if(!T.applied){let e=await a.query({where:{clientId:f.cid,externalRef:f.ref},limit:100}),i=oi(e.items);if(i)return i.data.status===`draft`&&await _l(t.cron,i.id,r),Ld(o,i.id,i.data,b,n.random,x);let s=Math.max(e.items.length,1)+1;if(y.value.delivery===`email`){let e=await si(f.cid,f.ref,s);if(!(await a.compareAndSet(e,null,y.value)).applied){let t=await a.get(e);return t?Ld(o,e,t,b,n.random):U(`INTERNAL`)}return await _l(t.cron,e,r),Fd(e,y.value,void 0)}if(w=await ee(s),!w.sent.ok)return Array.isArray(w.sent.error)?H(w.sent.error):U(`INTERNAL`);if(T=await a.compareAndSet(w.id,null,w.sent.value.envelope),!T.applied){let e=await a.get(w.id);return e?Ld(o,w.id,e,b,n.random):U(`INTERNAL`)}}let{id:E,sent:D}=w;if(!D.ok)return U(`INTERNAL`);await s.putMany(D.value.chunks);let te=await va(o,D.value.signer,S,n.random);D.value.envelope.delivery===`email`&&await rr(t,{signerId:D.value.signer.id,envelope:D.value.envelope,token:te,senderSetting:p.senderName,now:r});let O=[ci(y.value,`integration`),li(D.value.envelope,`integration`)];return await B(t).audit_events.putMany(await mr(E,O,v)),Fd(E,D.value.envelope,te)}function Fd(e,t,n,r=t.delivery===`inline`){return{ok:!0,envelopeId:e,status:t.status,...n!==void 0&&r?{signingToken:n}:{}}}function Id(e,t){let n=e.signer;return n.email===t.email&&n.as===t.as&&(n.participant?.name??null)===(t.participant?.name??null)}async function Ld(e,t,n,r,i,a){let o=n.signerIds[0],s=(n.status===`sent`||n.status===`in_progress`)&&Id(n,r.signer),c=r.delivery===`inline`&&s,l=a!==void 0&&r.delivery===`email`&&n.delivery===`email`&&s;if(!c&&!l||o===void 0)return Fd(t,n,void 0);let u=await _a(A(i),i,t=>e.updateIf(o,{where:{status:`pending`},set:{tokenHash:t}}));if(!u.value.applied)return Fd(t,n,void 0);if(c||!a)return Fd(t,n,u.token,!0);let d=await a(o,n,u.token);return{...Fd(t,n,void 0),...d?{resent:!0}:{}}}async function Rd(e,t,n){let{envelopes:r}=B(e),i=oi((await r.query({where:{clientId:t.cid,externalRef:t.ref},limit:100})).items);if(!i)return{ok:!0,status:`none`};let a=i.data.signer;if(a.name===t.signer.name.trim()&&a.email===t.signer.email.trim().toLowerCase()&&a.as===(t.as??`self`)&&(a.participant?.name??null)===(t.participant?.name.trim()??null)||i.data.status===`completed`)return Fd(i.id,i.data,void 0);let o=await R(r,i.id,i.data.status,`voided`,{closedAt:n,updatedAt:n});return o.ok?(await xa(e,i.id,o.value,{type:`envelope.voided`,at:n,actor:`integration`}),Fd(i.id,o.value,void 0)):U(`ENVELOPE_CLOSED`)}const zd=(e,t)=>Pd(e.input,t),Bd=64*1024,Vd=[{name:`public/envelopes/from-intent`,methods:[`POST`],body:`json`,maxBytes:16*1024},{name:`public/session`,methods:[`POST`],body:`json`,maxBytes:8*1024},{name:`public/otp/send`,methods:[`POST`],body:`json`,maxBytes:8*1024},{name:`public/otp/verify`,methods:[`POST`],body:`json`,maxBytes:8*1024},{name:`public/submit`,methods:[`POST`],body:`json`,maxBytes:256*1024},{name:`public/decline`,methods:[`POST`],body:`json`,maxBytes:8*1024},{name:`public/download`,methods:[`GET`],body:`none`,response:`raw`},{name:`public/verify`,methods:[`POST`],body:`json`,maxBytes:8*1024},{name:`public/receipts/lookup`,methods:[`POST`],body:`json`,maxBytes:8*1024},{name:`public/templates/catalog`,methods:[`POST`],body:`json`,maxBytes:Bd},{name:`public/self-serve/start`,methods:[`POST`],body:`json`,maxBytes:Bd}];async function Hd(){return oe({code:`NOT_FOUND`}).body}function Ud(e={}){let t={};for(let n of Vd)t[n.name]={public:!0,methods:[...n.methods],request:n.maxBytes===void 0?{body:n.body}:{body:n.body,maxBytes:n.maxBytes},...n.response?{response:n.response}:{},handler:e[n.name]??Hd};return t}const Wd=e=>Number(/_(\d+)$/.exec(e)?.[1]??0);function Gd(e){let t;for(let n of e)(!t||Wd(n.id)>Wd(t.id)||Wd(n.id)===Wd(t.id)&&n.data.createdAt>t.data.createdAt)&&(t=n);return t}async function Kd(e,t,n=Date.now()){let r=cd(t),i=await lt({token:V(e).request,now:n,getClient:r.getClient});if(!i.ok)return U(i.error);let{cid:a,ref:o}=i.value,s=Gd((await B(t).envelopes.query({where:{clientId:a,externalRef:o},limit:100})).items.filter(e=>e.data.clientId===a&&e.data.externalRef===o));if(!s)return{ok:!0,state:`none`,receipt:null};if(!Or(s.data.status))return{ok:!0,state:`pending`,receipt:null};let c=await ld(s.id,s.data,r.settings().integrationMasterKey);return c?{ok:!0,state:`terminal`,receipt:c}:U(`INTERNAL`)}const qd=(e,t)=>Kd(e.input,t),Jd=/^[0-9a-f]{64}$/,Yd=async(e,t)=>{let n=V(e.input).sha256,r=typeof n==`string`?n.toLowerCase():``;if(!Jd.test(r))return H([{path:`sha256`,code:`invalid`}]);if(!(await Sn({get:e=>t.kv.get(e),set:(e,n)=>t.kv.set(e,n)},e.requestMeta?.ip??`unknown`,Date.now(),{scope:`esign-verify`,limit:20,windowSeconds:600,salt:`esign-verify/1`})).ok)return U(`RATE_LIMITED`);let{envelopes:i,audit_events:a}=B(t),o=(await i.query({where:{pdfSha256:r},limit:1})).items[0];if(!o||o.data.status!==`completed`)return{ok:!0,matched:!1};let s=o.data,{items:c}=await a.query({where:{envelopeId:o.id},orderBy:{seq:`asc`},limit:101}),l=null;if(c.length<=100){let e=c.map(e=>e.data),t=await br(o.id,e);l=t.ok&&s.docSha256!==null&&e.at(-1)?.type===`envelope.completed`&&await Sr(s.docSha256,t.value.head)===s.finalHash}return{ok:!0,matched:!0,status:s.status,completedAt:s.completedAt,finalHash:s.finalHash,chainVerified:l}},Xd=[{name:er,schedule:`* * * * *`},{name:xl,schedule:`0 * * * *`},{name:Tl,schedule:`23 3 * * *`},{name:dl,schedule:`17 * * * *`}],Zd=Ud({"public/envelopes/from-intent":zd,"public/download":fa,"public/verify":Yd,"public/receipts/lookup":qd,"public/templates/catalog":dd,...Md}),Qd={hooks:{"plugin:activate":async(e,t)=>{await Dn(t,Xd)},cron:async(e,t)=>{await kn(e,t,Xd,Date.now())||await ar(e,t)||await Fa(e,t)||await bl(e,t)||await wl(e,t)||await Ll(e,t)||await pl(e,t)||await ta(e,t)}},routes:{...Zd,...nd,...ru,...Aa,admin:jn(nd.admin,An),"templates/create":jn(ru[`templates/create`]),"public/verify":jn(Zd[`public/verify`])}},$d={publicKey:`Trv2FjPQUPvm0izcO5IyqAZ5hse1-WShywKnN2s3ijg`,product:`esign`,buildDate:`2026-10-30`},ef=`esign-route-`,tf=e=>`${ef}${e}`;function nf(e,t,n,r=0){return e.cron?.schedule(tf(t),{schedule:N(n),data:{envelopeId:t,attempt:r}})}const rf=async(e,{envelopeId:t,envelope:n,signer:r,set:i,now:a})=>{let{signers:o}=B(e);if(n.routing===`sequential`&&r.data.order>1){let e=await o.getMany(n.signerIds);if(!Ps(`sequential`,r.data,[...e.values()]))return U(`SIGNING_OUT_OF_TURN`)}return(await o.updateIf(r.id,{where:{status:`pending`},set:i})).applied?(await nf(e,t,Date.parse(a)),{ok:!0,status:`in_progress`,signedAt:a}):U(`ENVELOPE_CLOSED`)};async function af(e,t,n,r=0){let{envelopes:i,signers:a,audit_events:o}=B(e),s=await i.get(t);if(!s||s.signerIds.length<2||s.status===`completed`||s.personalPurgedAt)return`skipped`;let[c,l]=await Promise.all([a.getMany(s.signerIds),o.query({where:{envelopeId:t},orderBy:{seq:`asc`},limit:100})]),u=s.signerIds.flatMap(e=>{let t=c.get(e);return t?[{id:e,data:t}]:[]}),d=N(n),f=L(e),p=zs(s,u,l.items.map(e=>e.data),d),m=f?p.invite:void 0,h=m||!p.invite?p.inputs:p.inputs.filter(e=>e.type!==`signer.invited`);if(h.length===0&&!m)return`idle`;if(l.hasMore)return e.log.error(`several-signer envelope has too many audit events to route`,{envelopeId:t}),`gave-up`;let g=await hr(t,l.items.at(-1)?.data??null,h,s.piiSalt),_=async()=>r+1>=5?(e.log.error(`several-signer envelope not routed: the chain never settled`,{envelopeId:t}),`gave-up`):(await nf(e,t,n+6e4,r+1),`retry`);if(p.complete){let r=await Sr(s.docSha256??``,g.at(-1)?.data.hash??``);if(!(await R(i,t,s.status,`completed`,{completedAt:d,finalHash:r,updatedAt:d})).ok)return _();if(!await vr(o,g))throw Error(`audit chain contention`);return await $i(e.cron,t,n),`completed`}return g.length>0&&!await vr(o,g)?_():m?(await of(e,s,m,f,n),`invited`):`audited`}async function of(e,t,n,r,i){let a=N(i),o=await e.settings.get(`senderName`),s=await _a(A(),void 0,t=>B(e).signers.updateIf(n,{where:{status:`pending`,waiting:!0},set:{tokenHash:t,invitedAt:a,waiting:!1}}));if(!s.value.applied)return;let{email:c,name:l}=s.value.data;await I(e).put(Us(n),Ws(Qn({to:c,signerName:l,title:t.title,sender:tr(e,o),link:`${r}/sign/${s.token}`,expiresAt:t.expiresAt}),i))}async function sf(e,t){if(!e.name.startsWith(ef))return!1;let n=e.data?.envelopeId,r=e.data?.attempt;return typeof n==`string`&&n.length>0&&await af(t,n,Date.now(),typeof r==`number`&&Number.isSafeInteger(r)?r:0),!0}const cf=`reminders`,lf=`reminders-more`;function uf(e,t){let n=t.find(e=>e.status!==`signed`);return e.routing===`sequential`&&n?.waiting===!0&&Ps(`sequential`,n,t)}async function df(e,t,n,r){let i=L(e);if(!i)return;let a=await e.settings.list(),o=e=>a.find(t=>t.key===e)?.value,s=o(`licenceKey`);if(!ce(await t.check({settings:{get:async()=>s},site:e.site}),`new`).ok)return;let c=Bs(o(`reminderCadenceDays`)),{envelopes:l,signers:u}=B(e),d=await l.query({where:{status:{in:[`sent`,`in_progress`]},expiresAt:{gt:N(n)}},orderBy:{expiresAt:`asc`},limit:50,...r?{cursor:r}:{}}),f=d.items.filter(e=>Date.parse(e.data.sentAt??``)+c*864e5<=n),p=f.flatMap(e=>e.data.signerIds),m=p.length>0?await u.getMany(p):new Map,h=e=>e.data.signerIds.flatMap(e=>{let t=m.get(e);return t?[{id:e,data:t}]:[]}),[g,..._]=f.flatMap(e=>h(e).filter(t=>Vs(e.data,t.data,{now:n,cadenceDays:c})).map(t=>({envelope:e,signer:t})));if(g)await ff(e,g.envelope,g.signer,i,o(`senderName`),n);else{let t=f.find(e=>uf(e.data,h(e).map(e=>e.data)));t&&await nf(e,t.id,n)}if(_.length>0||d.hasMore&&d.cursor){let t=_.length>0?r:d.cursor;await e.cron?.schedule(lf,{schedule:N(n+6e4),...t?{data:{cursor:t}}:{}})}}async function ff(e,t,n,r,i,a){let{signers:o,audit_events:s}=B(e),c=N(a),l=(n.data.reminders??0)+1,u=await _a(A(),void 0,e=>o.updateIf(n.id,{where:{status:`pending`,tokenHash:n.data.tokenHash},set:{tokenHash:e,remindedAt:c,reminders:l}}));if(!u.value.applied)return!1;if(await I(e).put(Us(n.id),Ws(Hs({to:n.data.email,signerName:n.data.name,title:t.data.title,sender:tr(e,i),link:`${r}/sign/${u.token}`,expiresAt:t.data.expiresAt}),a)),!(await gr(s,t.id,Is(n.data,c,l),{salt:t.data.piiSalt})).ok)throw Error(`audit chain contention`);return!0}async function pf(e,t,n,r=Date.now()){if(e.name===Tn)return await t.cron?.schedule(cf,{schedule:`29 * * * *`}),!1;if(e.name!==cf&&e.name!==lf)return!1;let i=e.name===lf?e.data?.cursor:void 0;return await df(t,n,r,typeof i==`string`&&i.length>0?i:void 0),!0}const mf=`mcp-send-`,hf=e=>(Qd.routes??{})[e].handler,gf=e=>typeof e==`object`&&e&&!Array.isArray(e)?e:{},_f=()=>({ok:!1,error:{code:`SITE_URL_MISSING`,message:nr}});async function vf(e,t){let{signers:n,routing:r,...i}=gf(e.input);if(!Array.isArray(n)||n.length<1||n.length>10)return H([{path:`signers`,code:`INVALID_SIGNERS`}]);if(n.length>1)return Ks({...e,input:{...i,signers:n,routing:r??`parallel`}},t);if(!L(t))return _f();let a=await hf(`envelopes/create`)({...e,input:{...i,signer:n[0]}},t);if(!a.envelope)return a;let o=e.user?.id;return await t.cron?.schedule(`${mf}${a.envelope.id}`,{schedule:N(),data:{envelopeId:a.envelope.id,...typeof o==`string`?{userId:o}:{}}}),{...a,sending:!0}}async function yf(e,t){if(!e.name.startsWith(mf))return!1;let n=e.data?.userId;return await hf(`envelopes/send`)({input:{id:e.name.slice(9)},...typeof n==`string`?{user:{id:n}}:{}},t),!0}async function bf(e,t){let{snapshot:n,...r}=gf(await hf(`envelopes/get`)(e,t));return r}async function xf(e,t){let n=gf(e.input).id;if(typeof n!=`string`||n.length===0||n.length>100)return H([{path:`id`,code:`INVALID_INPUT`}]);let r=L(t);if(!r)return _f();let{envelopes:i,signers:a}=B(t),o=await i.get(n);if(!o)return U(`ENVELOPE_NOT_FOUND`);if(o.status!==`sent`&&o.status!==`in_progress`)return U(`ENVELOPE_CLOSED`);let s=Date.now(),c=await a.getMany(o.signerIds),[l,...u]=o.signerIds.flatMap(e=>{let t=c.get(e);return t&&Vs(o,t,{now:s,cadenceDays:.041666666666666664})?[{id:e,data:t}]:[]});return l?await ff(t,{id:n,data:o},l,r,await t.settings.get(`senderName`),s)?{ok:!0,reminded:{signer:l.data.order},remaining:u.length}:{ok:!1,error:{code:`SIGNER_CHANGED`,message:`The signer's status changed. Try again.`}}:{ok:!1,error:{code:`NOTHING_TO_REMIND`,message:`No signer is due a reminder: each has signed, is not yet invited, was emailed in the last hour or has had the most reminders.`}}}const Sf=e=>({permission:`plugins:manage`,handler:e});function Cf(e){return{"pro/mcp/templates":Sf(hf(`templates/list`)),"pro/mcp/send":e.gate(`esign/envelope-send`,Sf(vf)),"pro/mcp/status":Sf(bf),"pro/mcp/remind":e.gate(`new`,Sf(xf)),"pro/mcp/void":Sf(hf(`envelopes/void`))}}const wf=[`sent`,`in_progress`],Tf=(e,t,n={})=>({ok:!1,error:{code:e,message:t,...n}}),Ef=(e,t)=>typeof e==`object`&&e?e[t]:void 0;function Df(e){let t=Ef(e,`token`);return typeof t==`string`&&t.length>0&&t.length<=200?t:null}function Of(e){try{return e!==void 0&&new URL(e.url).searchParams.has(`token`)}catch{return!1}}async function kf(e,t,n,r,i){return!(await Sn({get:t=>e.kv.get(t),set:(t,n)=>e.kv.set(t,n)},t.requestMeta?.ip??`unknown`,i,{scope:n,limit:r,windowSeconds:600,salt:`esign-otp/1`})).ok}async function Af(e,t,n){let{signers:r,envelopes:i}=B(e),a=(await r.query({where:{tokenHash:await j(t)},limit:1})).items[0];if(!a||a.data.status!==`pending`||!await he(t,a.data.tokenHash))return{error:U(`SIGNING_TOKEN_INVALID`)};let o=a.data.envelopeId,s=await i.get(o);return s?wf.includes(s.status)?s.expiresAt!==null&&s.expiresAt<=n?{error:U(`SIGNING_TOKEN_EXPIRED`)}:s.otp?{signer:{id:a.id,data:a.data},envelope:s,envelopeId:o}:{error:Tf(`OTP_NOT_REQUIRED`,`This document does not need a code.`)}:{error:U(`ENVELOPE_CLOSED`)}:{error:U(`ENVELOPE_NOT_FOUND`)}}const jf=e=>`Your code to sign: ${e.title}`,Mf=e=>`Your one-time code is ${e}\n\nIt expires in ${mo/6e4} minutes. Enter it on the signing page to continue. If you did not ask for it, ignore this email; nobody can sign for you without it. Never share this code.`;async function Nf(e,t){if(Of(e.request))return U(`TOKEN_IN_QUERY`);let n=Df(e.input);if(n===null)return H([{path:`token`,code:`INVALID_INPUT`}]);let r=Date.now();if(await kf(t,e,`otp-send`,10,r))return U(`RATE_LIMITED`);let i=await Af(t,n,N(r));if(i.error)return i.error;let{signer:a,envelope:o}=i;if(a.data.otpVerifiedAt)return{ok:!0,sent:!1,verified:!0};let s=a.data.otp??void 0,c=yo(s,r);if(!c.ok)return c.code===`OTP_WAIT`?Tf(`OTP_WAIT`,`A code was sent a moment ago. Please wait before asking for another.`,{retryAfterSeconds:c.retryAfterSeconds}):U(`RATE_LIMITED`);let l=go();await B(t).signers.updateIf(a.id,{where:{status:`pending`},set:{otp:await bo(l,a.id,r,c),otpTries:0}});try{if(!t.email)throw Error(`no email`);await t.email.send({to:a.data.email,subject:jf(o),text:Mf(l)})}catch{return await B(t).signers.updateIf(a.id,{where:{status:`pending`},set:{otp:s??null,otpTries:a.data.otpTries??5}}),Tf(`OTP_SEND_FAILED`,`We could not email a code. Please try again shortly.`)}return{ok:!0,sent:!0,expiresInSeconds:mo/1e3}}async function Pf(e,t){if(Of(e.request))return U(`TOKEN_IN_QUERY`);let n=Df(e.input),r=_o(Ef(e.input,`code`));if(n===null||r===null)return H([{path:n===null?`token`:`code`,code:`INVALID_INPUT`}]);let i=Date.now();if(await kf(t,e,`otp-verify`,30,i))return U(`RATE_LIMITED`);let a=N(i),o=await Af(t,n,a);if(o.error)return o.error;let{signer:s,envelope:c,envelopeId:l}=o;if(s.data.otpVerifiedAt)return{ok:!0,verified:!0};let{signers:u,audit_events:d}=B(t),f=s.data.otp??void 0,p=s.data.otpTries??5,m=await xo(f&&{...f,attempts:p},r,s.id,i),h=()=>Tf(`OTP_LOCKED`,`Too many wrong codes. Ask for a new code.`);if(!m.ok&&m.code!==`OTP_INVALID`)return m.code===`OTP_EXPIRED`?Tf(`OTP_EXPIRED`,`That code has expired. Ask for a new code.`):h();if(!(await u.updateIf(s.id,{where:{status:`pending`,otpTries:{lt:5}},delta:{otpTries:{inc:1}}})).applied)return h();if(!m.ok)return Tf(`OTP_INVALID`,`That code is not right.`,{attemptsLeft:m.attemptsLeft});if(!(await gr(d,l,{type:`otp.verified`,at:a,actor:`signer`,data:{method:`email`,...Ga(c.signerIds.length>1?s.data.order:void 0)},personal:{...e.requestMeta?.ip?{ip:e.requestMeta.ip}:{},...e.requestMeta?.userAgent?{ua:e.requestMeta.userAgent}:{}}},{salt:c.piiSalt})).ok)throw Error(`audit chain contention`);return await u.updateIf(s.id,{where:{status:`pending`,otpVerifiedAt:null},set:{otpVerifiedAt:a,otp:null}}),{ok:!0,verified:!0}}const Ff=/^[!-~]$/;function If(e){let t=`/`;for(let n of e){let e=n.charCodeAt(0);t+=Ff.test(n)&&!`()<>[]{}/%#`.includes(n)?n:`#${(e&255).toString(16).padStart(2,`0`)}`}return t}function Lf(e){if(!Number.isFinite(e))return`0`;if(Number.isInteger(e))return String(e);let t=e.toFixed(6).replace(/0+$/,``).replace(/\.$/,``);return t===`-0`?`0`:t}function Rf(e){if(e===null)return`null`;if(typeof e==`boolean`)return String(e);if(typeof e==`number`)return Lf(e);if(e instanceof Ao)return If(e.name);if(e instanceof Mo)return`${e.num} ${e.gen} R`;if(e instanceof jo){let t=``;for(let n=0;n<e.bytes.length;n++)t+=e.bytes.charCodeAt(n).toString(16).padStart(2,`0`);return`<${t}>`}return Array.isArray(e)?`[${e.map(Rf).join(` `)}]`:`<<${[...e].map(([e,t])=>`${If(e)} ${Rf(t)}`).join(` `)}>>`}const zf=(e,t=``)=>`<< /Length ${e.length}${t} >>\nstream\n${e}\nendstream`;var Bf=class{objects=new Map;next;constructor(e){this.file=e,this.next=e.size}add(e){let t=new Mo(this.next++,0);return this.objects.set(t.num,{gen:0,body:e}),t}replace(e,t){this.objects.set(e.num,{gen:this.file.genOf(e.num),body:t})}bytes(){let{file:e}=this,t=e.bytes.length,n=e.bytes[t-1],r=n===10||n===13?``:`
54
- `,i=new Map,a=(e,n,a)=>{i.set(e,t+r.length),r+=`${e} ${n} obj\n${a}\nendobj\n`};for(let e of[...this.objects.keys()].sort((e,t)=>e-t)){let t=this.objects.get(e);a(e,t.gen,t.body)}let o=[`Root`,`Info`,`ID`].filter(t=>e.trailer.has(t)).map(t=>` ${If(t)} ${Rf(e.trailer.get(t))}`).join(``),s=e=>{let t=[];for(let n of e){let e=t.at(-1);e&&e[0]+e[1].length===n?e[1].push(n):t.push([n,[n]])}return t},c=e=>this.objects.get(e)?.gen??0;if(e.xrefKind===`table`){let n=t+r.length;r+=`xref
55
- `;for(let[e,t]of s([...i.keys()].sort((e,t)=>e-t))){r+=`${e} ${t.length}\n`;for(let e of t)r+=`${String(i.get(e)).padStart(10,`0`)} ${String(c(e)).padStart(5,`0`)} n \n`}r+=`trailer\n<< /Size ${this.next}${o} /Prev ${e.startxref} >>\nstartxref\n${n}\n%%EOF\n`}else{let n=this.next++,a=t+r.length;i.set(n,a);let l=[...i.keys()].sort((e,t)=>e-t),u=``;for(let e of l){let t=i.get(e),n=c(e);u+=String.fromCharCode(1,t>>>24&255,t>>>16&255,t>>>8&255,t&255,n>>8&255,n&255)}let d=s(l).map(([e,t])=>`${e} ${t.length}`).join(` `);r+=`${n} 0 obj\n${zf(u,` /Type /XRef /Size ${this.next} /W [1 4 2] /Index [${d}]${o} /Prev ${e.startxref}`)}\nendobj\nstartxref\n${a}\n%%EOF\n`}let l=new Uint8Array(t+r.length);l.set(e.bytes);for(let e=0;e<r.length;e++)l[t+e]=r.charCodeAt(e);return l}};function Vf(e){let[t,n,r,i]=e.box;switch(e.rotate){case 90:return[0,1,-1,0,r,n];case 180:return[-1,0,0,-1,r,i];case 270:return[0,-1,1,0,t,i];default:return[1,0,0,1,t,n]}}function Hf(e,t,n){let r=[];for(let i of e){let{x:e,y:a,w:o,h:s}=i.box,c=t-a-s;if(i.kind===`text`){let t=Kt(i.text.replace(/\s+/g,` `).trim());if(!t)continue;let a=i.font===`italic`?`italic`:`regular`,l=Yt(t,1,a),u=Math.max(4,Math.min(14,s*.75,l>0?(o-2)/l:14)),d=c+Math.max(0,(s-u*.72)/2),f=a===`italic`?n.italic:n.regular;r.push(`BT ${If(f)} ${P(u)} Tf 0 0 0 rg ${P(e+1)} ${P(d)} Td ${Zt(t)} Tj ET`)}else{let t=[`0.05 0.1 0.45 RG 1.2 w 1 J 1 j`],n=t=>P(e+Math.min(1,Math.max(0,typeof t==`number`?t:0))*o),a=e=>P(c+s-Math.min(1,Math.max(0,typeof e==`number`?e:0))*s);for(let e of i.strokes){let r=e.filter(e=>Array.isArray(e)&&e.length>=2),[i]=r;if(i){t.push(`${n(i[0])} ${a(i[1])} m`);for(let e of r.length===1?r:r.slice(1))t.push(`${n(e[0])} ${a(e[1])} l`);t.push(`S`)}}t.length>1&&r.push(t.join(`
52
+ date 1 320 710 120 18`})],submit:{label:`Save`,actionId:`pdft.save`},blockId:`pdft:${t}`}),w({fields:[y(`signerName`,`Signer's name`),y(`signerEmail`,`Signer's email`),y(`title`,`Title (optional)`)],submit:{label:`Send for signature`,actionId:`pdft.send`},blockId:`pdft-send:${t}`}),g([_(`pdft.archive`,`Archive`,{value:t,style:`danger`}),Hc()])])}const Yc=(e,t)=>e?.startsWith(t)?e.slice(t.length):``,Xc=(e,t,n)=>e.pdfTemplates(t,n);async function Zc(e,t){let n=typeof t==`string`?t.trim():K(t?.id);if(!n)return Gc(e,h([q(`error`,`Choose a PDF first`)]));let r=await Xc(e,`upload`,{mediaId:n});if(r.ok!==!0)return Gc(e,h([q(`error`,`Not uploaded`,Wc(r))]));let i=r.template;return Jc(e,i.id,h([q(`info`,`Uploaded`,`Now set the fields to stamp, then send it.`)]))}async function Qc(e,t){if(t.type===`page_load`)return Gc(e);if(t.type===`block_action`){if(t.action_id===`pdft.upload`)return Zc(e,t.value);let n=K(t.value);if(t.action_id===`pdft.open`&&n)return Jc(e,n);if(t.action_id===`pdft.archive`&&n){let t=await Xc(e,`update`,{id:n,archived:!0});return Gc(e,h([t.ok?q(`info`,`Template archived`):q(`error`,`Not archived`,Wc(t))]))}return Gc(e)}let n=t.values;if(t.action_id===`pdft.save`){let r=Yc(t.block_id,`pdft:`),i=cs(typeof n.fields==`string`?n.fields:``);if(!i.ok)return Jc(e,r,h([q(`error`,`Not saved`,`Check field line ${i.error.join(`, `)}.`)]));let a=await Xc(e,`update`,{id:r,name:K(n.name),fields:i.value,signerFields:qc(typeof n.signerFields==`string`?n.signerFields:``)});return Jc(e,r,h([a.ok?q(`info`,`Saved`):q(`error`,`Not saved`,Wc(a))]))}if(t.action_id===`pdft.send`){let r=Yc(t.block_id,`pdft-send:`),i=await Xc(e,`send`,{templateId:r,signer:{name:K(n.signerName),email:K(n.signerEmail,254)},...K(n.title)?{title:K(n.title)}:{}});return i.ok===!0?Jc(e,r,h([i.invitation===`SITE_URL_MISSING`?q(`warning`,`Sent, but no email`,`Set the site URL so invitations can link to the signing page.`):q(`info`,`Sent for signature`)])):Jc(e,r,h([q(`error`,`Not sent`,Wc(i))]))}return Gc(e)}const $c=e=>e.type===`page_load`?e.page===`/pdf-templates`:e.action_id.startsWith(`pdft.`),el=()=>fc(`selfserve.back`,`Back to self-serve forms`);async function tl(e,t=[]){let[n,r,o]=await Promise.all([pc(e.ctx),e.ctx.settings.get(`turnstileSiteKey`),e.ctx.settings.get(`turnstileSecretKey`)]),s=typeof r==`string`&&r!==``&&typeof o==`string`&&o!==``;return G([i(`Self-serve forms`),...h([!s&&q(`warning`,`Turnstile is not set up`,`A public form needs both Cloudflare Turnstile keys in Settings. Until then the form on your page says it is unavailable.`)]),...t,a(`Mark a template here, then add the Self-serve request block to a page and pick the template. A visitor types their name, email address and the template's fields; the signing link goes only to that address. The cap is how many visitors can start in a day (UTC).`),l({columns:[c(`name`,`Template`),c(`state`,`Self-serve`,`badge`),c(`cap`,`Per day`),c(`edit`,``,`element`)],rows:n.map(({id:e,data:t})=>({name:t.name,state:Js(t)?`On`:`Off`,cap:Js(t)?String(Ys(t)):``,edit:_(`selfserve.open`,`Edit`,{value:e})})),pageActionId:`selfserve.page`,emptyText:`No active templates. Create one on the Templates page.`})])}async function nl(e,t,n=[]){let r=await B(e.ctx).templates.get(t);return!r||r.status!==`active`?G([i(`Self-serve forms`),...h([q(`error`,`Template not found`)]),g([el()])]):G([i(`Self-serve: ${r.name}`),...n,w({fields:[S(`enabled`,`Offer this template to visitors`,{initialValue:Js(r)}),b(`dailyCap`,`Visitors per day`,{initialValue:r.selfServeDailyCap??50,min:1,max:qs})],submit:{label:`Save`,actionId:`selfserve.save`},blockId:`selfserve:${t}`}),g([el()])])}async function rl(e,t,n){let r=t?.startsWith(`selfserve:`)?t.slice(10):``;if(!r)return tl(e,h([q(`error`,`Choose a template first`)]));let i=n.enabled===!0,a=n.dailyCap,o=typeof a==`number`?a:typeof a==`string`&&a.trim()!==``?Number(a):void 0,s=await e.markSelfServe({id:r,enabled:i,...o===void 0?{}:{dailyCap:o}});if(s.ok!==!0)return nl(e,r,h([q(`error`,`Not saved`,s.error?.code===`BAD_REQUEST`?`The daily cap must be a whole number from 1 to ${qs}.`:s.error?.message??`The change was refused.`)]));let c=s.template;return tl(e,h([q(`info`,c.public?`Self-serve is on`:`Self-serve is off`,c.public?`Up to ${c.selfServeDailyCap} visitors a day can start from this template.`:`Visitors can no longer start from this template.`)]))}const il=e=>e.type===`page_load`?e.page===`/self-serve`:e.action_id.startsWith(`selfserve.`);async function al(e,t){return t.type===`page_load`?tl(e):t.type===`form_submit`?rl(e,t.block_id,t.values):t.action_id===`selfserve.open`?nl(e,K(t.value,200)):tl(e)}const ol=e=>typeof e==`function`?e:e.handler;function sl(e){try{return new URL(e.request?.url??``).origin}catch{return`http://localhost`}}function cl(e){let t=(t,n)=>ol(e.gate(t,{handler:n})),n=t(`esign/envelope-send`,Ks),r=t(`esign/envelope-send`,Oo),i=t(`new`,dc),a={upload:t(`new`,Ts),update:t(`new`,Es),send:t(`esign/envelope-send`,Ds)};return e=>{let t=ol(e),o=async(e,o)=>{let s=e.input,c=e.user??null,l=e=>t=>e({input:t,user:c},o),u={ctx:o,origin:sl(e),now:Date.now(),user:c,sendSeveral:l(n),startBulk:l(r),markSelfServe:l(i),pdfTemplates:(e,t)=>l(a[e])(t)};if(Cc(s))return wc(u,s);if(il(s))return al(u,s);if($c(s))return Qc(u,s);if(s.type!==`page_load`&&Bc(s.action_id))return Vc(u,s);let d=s.type===`page_load`&&s.page===`/envelopes`||s.type===`block_action`&&s.action_id===`envelopes.back`?()=>Pc(u):s.type===`block_action`&&s.action_id===`envelope.open`?()=>Rc(u,String(s.value??``).trim().slice(0,200)):null;if(!d)return t(e,o);let[f,p]=await Promise.all([t(e,o),d()]),m=f?.blocks;return Array.isArray(m)&&p.length>0?{...f,blocks:[...m,...p]}:f};return typeof e==`function`?o:{...e,handler:o}}}async function ll(e,t,n,r){let i=To(e),a=await i.getMany([t,oo(t),ao(t,n),so(t)]),o=a.get(t),s=a.get(ao(t,n));if(!o||o.kind!==`job`||!s)return`skipped`;let c=N(r),l=n+1>=o.pages,u=async()=>{await e.cron?.schedule(lo(t,n+1),{schedule:c})},d=L(e);if(o.status===`cancelled`||a.has(so(t))||!d)return await i.deleteMany([ao(t,n),...l?[oo(t),so(t)]:[]]),(o.status!==`cancelled`||!l)&&await i.putMany([{id:t,data:{...o,status:`cancelled`,updatedAt:c}}]),l||await u(),`cancelled`;let f=a.get(oo(t))?.template,p=s.rows.filter(e=>e.status===`pending`),m=new Map,h=[],g={chunks:[],signers:[],envelopes:[],audit:[],mail:[]},_=tr(e,o.senderName);await Promise.all(p.map(async e=>{let n=t=>{m.set(e.seq,{seq:e.seq,status:`failed`,code:t}),h.push({seq:e.seq,code:t})};if(!f||!e.name||!e.email)return n(`TEMPLATE_NOT_FOUND`);let i=co(t,e.seq),a=cr(),s=Qr({templateId:o.templateId,templateVersion:o.templateVersion,title:o.title,signer:{name:e.name,email:e.email,as:`self`},fieldValues:e.fields??{}},f,{now:c,piiSalt:a});if(!s.ok)return n(s.error[0]?.code??`BAD_REQUEST`);let l=A(),u=await ai(i,s.value,f,{now:c,tokenHash:await j(l),expiryDays:o.expiryDays});if(!u.ok)return n(Array.isArray(u.error)?u.error[0]?.code??`BAD_REQUEST`:`ENVELOPE_CLOSED`);let p={...u.value.envelope,...o.otp?{otp:!0}:{}},v=li(p,`admin`,o.createdBy),y=[{...v,data:{...v.data,source:`bulk`}},ui(p,`admin`,o.createdBy)];g.chunks.push(...u.value.chunks),g.signers.push(u.value.signer),g.envelopes.push({id:i,data:p}),g.audit.push(...await mr(i,y,a)),g.mail.push({id:Us(u.value.signer.id),data:Ws(Qn({to:e.email,signerName:e.name,title:p.title,sender:_,link:`${d}/sign/${l}`,expiresAt:p.expiresAt}),r)}),m.set(e.seq,{seq:e.seq,status:`sent`,envelopeId:i})}));let v=B(e),y=async(e,t)=>{t.length>0&&await e.putMany(t)};await y(v.snapshots,g.chunks),await y(v.signers,g.signers),await y(v.envelopes,g.envelopes),await y(v.audit_events,g.audit),await y(I(e),g.mail);let b=s.rows.map(e=>m.get(e.seq)??e),x=[...m.values()].filter(e=>e.status===`sent`).length,S=[{id:t,data:{...o,sent:o.sent+x,failed:o.failed+h.length,failures:[...o.failures,...h].slice(0,50),status:l?`done`:`running`,updatedAt:c}},{id:ao(t,n),data:{...s,rows:b}}];return await i.putMany(S),l?await i.deleteMany([oo(t)]):await u(),`sent`}async function ul(e,t,n=Date.now()){let r=fo(e.name);return r?(await ll(t,r.jobId,r.page,n),!0):!1}const dl=`expire`,fl=`expire-more`;async function pl(e,t){if(e.name!==dl&&e.name!==fl)return!1;let{envelopes:n}=B(t),r=N(),i=await n.query({where:{status:{in:[`sent`,`in_progress`]},expiresAt:{lt:r}},orderBy:{expiresAt:`asc`},limit:2});for(let{id:e,data:a}of i.items){let i=await kr(n,e,a.status,`expired`,{closedAt:r,updatedAt:r});i.ok&&await xa(t,e,i.value,{type:`envelope.expired`,at:r,actor:`system`})}return i.hasMore&&await t.cron?.schedule(fl,{schedule:N(Date.now()+6e4)}),!0}function ml(e){if(typeof e!=`string`)return null;let t=new TextEncoder().encode(e.trim());return t.length>=32?t:null}const hl=`intent-finish-`,gl=e=>`${hl}${e}`;function _l(e,t,n){return e?.schedule(gl(t),{schedule:N(n),data:{envelopeId:t}})}async function vl(e,t){let n=await te(e),r=await crypto.subtle.sign(`HMAC`,n,new TextEncoder().encode(`esign-invite/1.${t}`));return E(new Uint8Array(r))}async function yl(e,t,n){let{envelopes:r,templates:i,snapshots:a,signers:o,audit_events:s}=B(e),c=await r.get(t);if(!c||c.status!==`draft`||c.delivery!==`email`||!c.clientId)return`skipped`;let l=R(c.templateId,c.templateVersion),[u,d]=await Promise.all([i.getMany([c.templateId,l]),e.settings.list()]),f=Object.fromEntries(d.map(e=>[e.key,e.value])),p=Jr(u.get(c.templateId),u.get(l),c.templateVersion);if(!p.ok)return`skipped`;let m=ml(f.integrationMasterKey);if(!m)return`skipped`;let h=await vl(m,t),g=await ai(t,c,p.value,{now:N(n),tokenHash:await j(h),expiryDays:ha(f.expiryDays)});if(!g.ok)return`skipped`;await a.putMany(g.value.chunks);let _=await va(o,g.value.signer,h);await rr(e,{signerId:g.value.signer.id,envelope:g.value.envelope,token:_,senderSetting:f.senderName,now:n});let v=[li(c,`integration`),ui(g.value.envelope,`integration`)];return await s.putMany(await mr(t,v,c.piiSalt)),(await kr(r,t,`draft`,`sent`,g.value.envelope)).ok?`sent`:`skipped`}async function bl(e,t){if(!e.name.startsWith(hl))return!1;let n=e.data?.envelopeId;return typeof n==`string`&&n.length>0&&await yl(t,n,Date.now()),!0}const xl=`nonce-sweep`,Sl=`nonce-sweep-more`;async function Cl(e){let{nonces:t,cron:n,now:r,page:i=100,pages:a=3}=e,o=N(r),s=0,c=!1;for(let e=0;e<a;e++){let e=await t.query({where:{expiresAt:{lt:o}},orderBy:{expiresAt:`asc`},limit:i});if(e.items.length===0||(s+=await t.deleteMany(e.items.map(e=>e.id)),c=e.hasMore===!0,!c))break}return c&&await n?.schedule(Sl,{schedule:N(r+6e4)}),{deleted:s,more:c}}async function wl(e,t){if(e.name!==xl&&e.name!==Sl)return!1;let n=t.storage.nonces;return await Cl({nonces:n,cron:t.cron,now:Date.now()}),!0}const Tl=`retention`,El=`retention-more`,Dl=`cron:retention`,Ol=e=>e.status===`sent`||e.status===`in_progress`,kl=e=>Ol(e)?null:Date.parse(e.completedAt??e.closedAt??e.updatedAt),Al=(e,t,n,r)=>{let i=e.find(e=>e.key===t)?.value;return typeof i==`number`&&Number.isFinite(i)?Math.min(r,Math.max(1,Math.round(i))):n};function jl(e,t){let n=new Date(t);n.setUTCMonth(n.getUTCMonth()-Al(e,`retentionPersonalDataMonths`,12,120));let r=new Date(t);return r.setUTCFullYear(r.getUTCFullYear()-Al(e,`retentionSignedRecordsYears`,7,50)),{p:Math.max(n.getTime(),r.getTime()),r:r.getTime()}}function Ml(e,t){let{name:n,email:r,ip:i,ua:a,signature:o,fieldValues:s,declineReason:c,copyTokenHash:l,participant:u,...d}=t;return{...d,name:``,email:``,tokenHash:`purged:${e}`,...o?{signature:{kind:o.kind,sha256:o.sha256}}:{}}}function Nl(e,t){let{piiSalt:n,returnUrl:r,signerEmail:i,...a}=e;return{...a,signer:{name:``,email:``,as:e.signer.as},fieldValues:{},personalPurgedAt:t}}async function Pl(e,t,n){let r=new Set(t.filter(e=>e.data.status===`draft`).map(e=>e.id)),i=await e.audit_events.query({where:{envelopeId:{in:t.map(e=>e.id)}},limit:100,...n?{cursor:n}:{}}),a=i.items.filter(e=>!r.has(e.data.envelopeId)&&e.data.personal!==null),o=i.items.filter(e=>r.has(e.data.envelopeId)).map(e=>e.id);return a.length>0&&await e.audit_events.putMany(a.map(e=>({id:e.id,data:xr(e.data)}))),o.length>0&&await e.audit_events.deleteMany(o),i.hasMore?i.cursor:void 0}async function Fl(e,t,n){let r=N(n),i=t.filter(e=>e.data.status!==`draft`),a=i.flatMap(e=>e.data.signerIds),o=a.length>0?await e.signers.getMany(a):new Map,s=a.flatMap(e=>{let t=o.get(e);return t?[{id:e,data:Ml(e,t)}]:[]});s.length>0&&await e.signers.putMany(s),i.length>0&&await e.envelopes.putMany(i.map(e=>({id:e.id,data:Nl(e.data,r)})));let c=t.filter(e=>e.data.status===`draft`).map(e=>e.id);c.length>0&&await e.envelopes.deleteMany(c)}async function Il(e,t){let n=B(e),r={...await e.kv.get(Dl)},i=!1;if(!r.phase||r.phase===`rl`)(await Cn(e.kv,t,3)).more?r.phase=`rl`:Object.assign(r,jl(await e.settings.list(`retention`),t),{phase:`personal`});else if(r.phase===`outbox`){let e=await n.outbox.query({where:{status:{in:[`sent`,`failed`]},nextAttemptAt:{lt:r.p}},limit:100});e.items.length>0&&await n.outbox.deleteMany(e.items.map(e=>e.id)),i=!e.hasMore}else{let e=r.phase===`personal`,i=e?r.p:r.r,a=await n.envelopes.query({where:{createdAt:{gte:(e?r.pf:r.rf)??``,lt:N(i)}},limit:10,...r.cursor?{cursor:r.cursor}:{}}),o=t=>e?t.personalPurgedAt:t.recordsPurgedAt,s=a.items.filter(({data:e})=>!o(e)&&(kl(e)??i)<i),c=s.length===0;if(!r.step&&s.length>0){if(e)r.acursor=await Pl(n,s,r.acursor);else{let e=await n.audit_events.query({where:{envelopeId:{in:s.map(e=>e.id)}},limit:100});if(e.items.length>0&&await n.audit_events.deleteMany(e.items.map(e=>e.id)),e.hasMore)r.acursor=`more`;else{delete r.acursor;let e=s.flatMap(e=>e.data.pdf?.ids??[]),t=s.flatMap(e=>e.data.snapshot?.ids??[]);e.length>0&&await n.artifacts.deleteMany(e),t.length>0&&await n.snapshots.deleteMany(t)}}r.acursor||(r.step=1)}else if(s.length>0){if(e)await Fl(n,s,t);else{let e=s.flatMap(e=>e.data.signerIds);e.length>0&&await n.signers.deleteMany(e);let r=N(t);await n.envelopes.putMany(s.map(({id:e,data:t})=>({id:e,data:{...t,title:``,signerIds:[],snapshot:null,pdf:null,pdfSha256:null,recordsPurgedAt:r}})))}c=!0}if(c){delete r.step;for(let{data:e}of a.items)!o(e)&&!s.some(t=>t.data===e)&&(!r.keep||e.createdAt<r.keep)&&(r.keep=e.createdAt);a.hasMore&&a.cursor?r.cursor=a.cursor:(r[e?`pf`:`rf`]=r.keep??N(i),delete r.cursor,delete r.keep,r.phase=e?`records`:`outbox`)}}return i&&delete r.phase,await e.kv.set(Dl,r),i||await e.cron?.schedule(El,{schedule:N(t)}),i}async function Ll(e,t,n=Date.now()){return e.name!==Tl&&e.name!==El?!1:(await Il(t,n),!0)}const Rl=e=>Ol(e)||e.status===`completed`&&!e.pdfSha256;async function zl(e,t){let n=B(e),r;if(t.includes(`@`)){let e=t.toLowerCase(),[i,a]=await Promise.all([n.signers.query({where:{email:e},limit:10}),n.envelopes.query({where:{signerEmail:e},limit:10})]),o=new Map(a.items.map(e=>[e.id,e.data])),s=[...new Set(i.items.map(e=>e.data.envelopeId))].filter(e=>!o.has(e));if(s.length>0)for(let[e,t]of await n.envelopes.getMany(s))o.set(e,t);r=[...o].slice(0,10).map(([e,t])=>({id:e,data:t}))}else{let e=await n.envelopes.get(t);r=e?[{id:t,data:e}]:[]}return{due:r.filter(e=>!Rl(e.data)&&!e.data.personalPurgedAt),open:r.filter(e=>Rl(e.data)).length}}async function Bl(e,t,n){let r=B(e),i=await Pl(r,t.due);if(i&&=await Pl(r,t.due,i),i)throw Error(`audit trail too long for one request`);await Fl(r,t.due,n),await r.outbox.deleteMany(t.due.flatMap(e=>[`complete-${e.id}`,...e.data.signerIds.map(e=>`invite-${e}`)]))}const Vl=new Set([`localhost`,`127.0.0.1`,`[::1]`]);function Hl(e=T){return E(e(32))}const Ul=e=>ml(e)===null;function Wl(e){let t=[];for(let n of e.split(/\r?\n/)){let e=n.trim();if(e===``)continue;let r;try{r=new URL(e)}catch{return{ok:!1,entry:e}}if(!(r.protocol===`https:`||r.protocol===`http:`&&Vl.has(r.hostname))||r.username||r.password||e.includes(`#`)||e.includes(`?`))return{ok:!1,entry:e};t.push(r.href)}return t.length>10?{ok:!1,entry:`too many entries`}:{ok:!0,entries:t}}async function Gl(e,t,n){let r=ml(t.masterKey);if(!r)return{ok:!1,code:`MASTER_KEY_MISSING`};let i=t.name.trim();if(i===``||i.length>100)return{ok:!1,code:`NAME_REQUIRED`};let a=Rt(n.random),o={name:i,clientId:a,createdAt:n.now,lastUsedAt:null,revokedAt:null,returnUrlAllowlist:t.returnUrlAllowlist};return await e.put(a,o),{ok:!0,client:o,pairing:It(a,await Lt(r,a))}}async function Kl(e,t,n){return(await e.updateIf(t,{where:{revokedAt:null},set:{revokedAt:n}})).applied}async function ql(e){return(await e.query({orderBy:{createdAt:`desc`},limit:100})).items.map(e=>e.data)}function Jl(e){let t=(e??``).split(`,`).filter(e=>e.trim()!==``).length;return t===0?{state:`missing`,canSaveSecrets:!1,keyCount:0,banner:{tone:`error`,message:`EMDASH_ENCRYPTION_KEY is not set, so secret settings (the integration master key and the Turnstile secret) cannot be saved. Set it in the site environment and restart.`}}:{state:`ready`,canSaveSecrets:!0,keyCount:t,banner:null}}function Yl(e){let t=`PLUGIN_SETTING_ENCRYPTION_KEY_MISSING`,n=e=>e.includes(t)||e.includes(`PluginSettingEncryptionError`);return typeof e==`string`?n(e):e instanceof Error?n(e.message)||e.name===`PluginSettingEncryptionError`:typeof e==`object`&&e?e.code===t:!1}const Xl=e=>e.storage.templates,Zl=e=>({...oe(`BAD_REQUEST`).body,...e?{issues:e}:{}}),Ql=()=>oe(`TEMPLATE_NOT_FOUND`).body;function $l(e){let t=V(e).id;return typeof t==`string`&&t.length>0&&t.length<=200&&!t.includes(`:`)?t:null}const eu=(e,t)=>({id:e,...t}),tu=(e,{body:t,...n})=>({id:e,...n});async function nu(e,t){let n=await Xl(e).get(t);return n&&n.status!==`version`?n:null}const ru={"templates/create":{handler:(async(e,t)=>{let n=crypto.randomUUID(),r=Mr(e.input,{id:n,now:N()});if(!r.ok)return Zl(r.error);let{head:i,versions:a}=r.value;return await Xl(t).putMany([{id:n,data:i},...a]),{ok:!0,template:eu(n,i)}})},"templates/update":{handler:(async(e,t)=>{let n=$l(e.input);if(!n)return Zl();let r=await nu(t,n);if(!r)return Ql();let i=Nr(r,e.input,{id:n,now:N()});return i.ok?(await Xl(t).putMany([{id:n,data:i.value.head},i.value.version]),{ok:!0,template:eu(n,i.value.head)}):Zl(i.error)})},"templates/get":{handler:(async(e,t)=>{let n=$l(e.input);if(!n)return Zl();let r=V(e.input).version;if(r!==void 0&&!(Number.isSafeInteger(r)&&r>=1))return Zl();let i=r,a=await Xl(t).getMany(i===void 0?[n]:[n,R(n,i)]),o=a.get(n);if(!o||o.status===`version`)return Ql();let s=i===void 0?o:a.get(R(n,i));if(!s)return Ql();let c=Array.from({length:o.version},(e,t)=>t+1);return{ok:!0,template:eu(n,{...s,status:o.status}),versions:c}})},"templates/list":{handler:(async(e,t)=>{let n=V(e.input).status??`active`;if(n!==`active`&&n!==`archived`)return Zl();let{items:r}=await Xl(t).query({where:{status:n},limit:200});return{ok:!0,templates:r.map(e=>tu(e.id,e.data)).sort((e,t)=>e.name<t.name?-1:e.name>t.name?1:0)}})},"templates/archive":{handler:(async(e,t)=>{let n=$l(e.input);if(!n)return Zl();let r=await nu(t,n);if(!r)return Ql();if(r.status===`archived`)return{ok:!0,template:eu(n,r)};let i=Pr(r,N());return await Xl(t).putMany([{id:n,data:i}]),{ok:!0,template:eu(n,i)}})}},iu=(e,t)=>({severity:`error`,title:e,...t?{message:t}:{}}),au=e=>B(e.ctx).clients;async function ou(e){return(await e.ctx.settings.list()).find(e=>e.key===`integrationMasterKey`)?.value}const su=e=>typeof e==`string`&&e.trim()!==``;function cu(e,t,n=[]){let r=ml(e)!==null,o=typeof e==`object`&&!!e,s=Jl(null).banner;return J([i(`Integrations`),...h([o&&s&&{severity:`error`,title:`Encryption key missing`,message:s.message},!r&&!o&&{severity:`warning`,title:su(e)?`Integration master key is too short`:`Integration master key not set`,message:`Clients are paired with secrets derived from the master key. Generate one here, or save one of at least 32 characters in Settings.`}]),...n,...r||o||su(e)?[]:[g([_(`integrations.generate-key`,`Generate master key`,{style:`primary`})])],i(`Clients`),l({columns:[c(`name`,`Name`),c(`clientId`,`Client id`),c(`created`,`Created`,`relative_time`),c(`status`,`Status`,`badge`),c(`revoke`,``,`element`)],rows:t.map(e=>({name:e.name,clientId:e.clientId,created:e.createdAt,status:e.revokedAt?`Revoked`:`Active`,...e.revokedAt?{}:{revoke:_(`client.revoke`,`Revoke`,{style:`danger`,value:e.clientId,confirm:{title:`Revoke this client?`,text:`Its intents and receipts are refused from now on. This cannot be undone; create a new client to pair again.`,confirm:`Revoke client`,deny:`Keep`,style:`danger`}})}})),pageActionId:`clients.page`,emptyText:`No clients yet.`}),a(`Events on this site: with the Events suite installed, an administrator pairs it in one click at /_events/pair (the client appears here as "Events on this site"; no string to copy).`),i(`Add a client`),a(`The pairing string is shown once, right after you create the client, and cannot be shown again. Paste it into the other plugin's settings. Return URLs: one per line, https (http only for localhost); leave blank to allow this site only.`),w({fields:[y(`name`,`Name`,{initialValue:``}),y(`returnUrlAllowlist`,`Allowed return URLs`,{multiline:!0,initialValue:``})],submit:{label:`Create client`,actionId:`client.create`}})])}async function lu(e,t,n=[]){return cu(t,await ql(au(e)),n)}async function uu(e){let[t,n]=await Promise.all([ou(e),ql(au(e))]);return cu(t,n)}async function du(e){let t=await ou(e);if(su(t))return lu(e,t,h([iu(`Key already set`,`Changing it would re-pair every client.`)]));let n=Hl();try{await e.ctx.settings.set(`integrationMasterKey`,n)}catch(n){if(!Yl(n))throw n;return lu(e,t,h([iu(`Encryption key missing`,Jl(null).banner?.message)]))}return lu(e,n,h([{severity:`info`,title:`Master key generated`}]))}async function fu(e,t){let n=await ou(e),r=(e,t)=>typeof e==`string`?e.slice(0,t):``,i=Wl(r(t.returnUrlAllowlist,2e3));if(!i.ok)return lu(e,n,h([iu(`Not created`,`Return URL not allowed: ${i.entry.slice(0,200)}`)]));let a=await Gl(au(e),{name:r(t.name,200),returnUrlAllowlist:i.entries,masterKey:n},{now:N(e.now)});return a.ok?lu(e,n,[...h([{severity:`warning`,title:`Copy the pairing string now`,message:`It is shown only this once and cannot be recovered. Treat it like a password.`}]),d({code:a.pairing})]):lu(e,n,h([iu(`Not created`,a.code===`MASTER_KEY_MISSING`?`Set the integration master key first (at least 32 characters), or generate one.`:`Give the client a name of up to 100 characters.`)]))}async function pu(e,t){let n=await Kl(au(e),t,N(e.now));return lu(e,await ou(e),h([n?{severity:`info`,title:`Client revoked`}:iu(`Not revoked`,`Unknown or already revoked.`)]))}const J=e=>({blocks:e}),Y=(e,t=200)=>typeof e==`string`?e.trim().slice(0,t):``,X=(e,t,n)=>t.handler({input:n,user:e.user??null},e.ctx),mu=e=>Aa[e],hu=e=>ru[e],gu={INVALID_NAME:`Give the template a name of up to 200 characters.`,INVALID_BODY:`The template text is required (up to 100,000 characters).`,INVALID_DESCRIPTION:`The description is too long (up to 1,000 characters).`,TEMPLATE_ARCHIVED:`This template is archived.`,INVALID_INTEGRATIONS:`Choose whether integrations may use the template.`,INVALID_TITLE:`The title is too long or has control characters.`,INVALID_SIGNER_NAME:`Enter the signer's name.`,INVALID_SIGNER_EMAIL:`Enter a valid email address for the signer.`,INVALID_FIELDS:`A field value is too long or not text.`,MISSING_FIELD:`A template field has no value.`,DOCUMENT_TOO_LARGE:`The document is too long to sign (up to 131,072 characters and 1,500 lines).`};function _u(e,t=`The change was refused.`){let n=Array.isArray(e.issues)?e.issues:[];return n.length>0?n.map(e=>gu[e.code??``]??`${e.path??`input`} (${e.code??`invalid`})`).join(` `):e.error?.message??t}const vu=(e,t,n)=>({severity:e,title:t,...n?{message:n}:{}}),Z=(e,t)=>vu(`error`,e,t),yu=(e,t)=>vu(`warning`,e,t),bu=(e,t)=>_(e,t,{style:`secondary`}),xu=(e,t)=>vu(`info`,e,t),Su=()=>bu(`envelopes.back`,`Back to envelopes`),Cu=()=>bu(`templates.back`,`Back to templates`),wu=e=>_(`envelope.open`,`Open envelope`,{value:e}),Tu={"envelope.created":`Envelope created`,"envelope.sent":`Envelope sent`,"signer.viewed":`Signer opened the document`,"signer.consented":`Signer gave consent`,"signer.signed":`Signer signed`,"signer.declined":`Signer declined`,"envelope.completed":`Envelope completed`,"envelope.declined":`Envelope declined`,"envelope.voided":`Envelope voided`,"envelope.expired":`Envelope expired`},Eu=e=>!L(e.ctx)&&yu(`Set the site URL`,nr);async function Du(e){let t=await or(e.ctx);return[Eu(e),t.state===`no_transport`&&yu(`No email transport`,`No email provider is configured, so signing invitations stay queued and are not delivered. Install an email provider plugin.`),t.failed>0&&yu(`${t.failed} email${t.failed===1?``:`s`} could not be delivered`,`Open the envelope and use Resend invitation if a signer never received theirs.`)]}async function Ou(e,t,n=[],r){let o=Er(t)?t:``,[s,u]=await Promise.all([X(e,mu(`envelopes/list`),{...o?{status:o}:{},...r?{cursor:r}:{}}),Du(e)]),d=typeof s.nextCursor==`string`?s.nextCursor:void 0,f=(s.envelopes??[]).map(e=>{let t=e.signer;return{title:e.title,signer:t?`${t.name??``} <${t.email??``}>`:``,status:e.status,created:e.createdAt,open:_(`envelope.open`,`Open`,{value:e.id})}});return J([i(`Envelopes`),...h(u),...n,w({fields:[x(`status`,`Status`,[{label:`Any status`,value:``},...Cr.map(e=>({label:e.replaceAll(`_`,` `),value:e}))],{initialValue:o})],submit:{label:`Filter`,actionId:`envelopes.filter`}}),a(`Newest first, 100 a page. Create an envelope from a template on the Templates page.`),l({columns:[c(`title`,`Title`),c(`signer`,`Signer`),c(`status`,`Status`,`badge`),c(`created`,`Created`,`relative_time`),c(`open`,``,`element`)],rows:f,pageActionId:`envelopes.page:${o}`,...d?{nextCursor:d}:{},emptyText:`No envelopes match.`}),i(ku),w({fields:[y(`subject`,`Signer email or envelope id`)],submit:{label:`Find`,actionId:`retention.preview`}})])}const ku=`Delete personal data`;async function Au(e,t,n){let r=await zl(e.ctx,t),a=r.due.length;return n&&a>0&&await Bl(e.ctx,r,e.now),J([i(ku),...h([{severity:n?`info`:`warning`,title:n&&a>0?`Personal data deleted`:a+r.open>0?`${a} envelope(s) to delete, ${r.open} kept for now`:`No envelopes found`,message:`Signed records stay for their own period; open envelopes and pending PDFs are skipped.`}]),g([...!n&&a>0?[_(`retention.erase`,ku,{style:`danger`,value:t,confirm:{title:`${ku}?`,text:`This cannot be undone.`,confirm:`Delete`,deny:`Keep`,style:`danger`}})]:[],Su()])])}async function ju(e,t){if(!t)return`missing`;let n=await B(e.ctx).outbox.get(`invite-${t}`);return n?n.status===`failed`?`failed`:`queued`:`missing`}async function Mu(e,t,n={}){let{envelopes:r,signers:s,audit_events:u}=B(e.ctx),d=n.envelope??await r.get(t);if(!d)return J([i(`Envelope`),...h([Z(`Envelope not found`,`It may have been removed.`)]),g([Su()])]);let f=d.status===`sent`||d.status===`in_progress`,[p,m,y]=await Promise.all([u.query({where:{envelopeId:t},orderBy:{seq:`asc`},limit:200}),n.signers?Promise.resolve(n.signers):d.signerIds.length>0?s.getMany(d.signerIds).then(e=>[...e].map(([e,t])=>({id:e,name:t.name,email:t.email,status:t.status}))):Promise.resolve([]),n.invite??(d.status===`sent`?ju(e,d.signerIds[0]):Promise.resolve(`n/a`))]),b=m[0],x=d.status===`sent`&&(y===`missing`||y===`failed`),S=null;if(d.status===`completed`&&!d.recordsPurgedAt)if(d.pdfSha256){let n=await ca(e.ctx,t,e.now);S=g([v(`Download signed PDF`,{kind:`external`,url:`${e.origin}${n.url}`},{appearance:`primary`})])}else S=a(`The signed PDF is still being prepared. Reload in a minute.`);let C=[d.status===`draft`&&_(`envelope.send`,`Send for signature`,{style:`primary`,value:t}),x&&_(`envelope.resend`,`Resend invitation`,{style:`primary`,value:t}),(d.status===`draft`||f)&&_(`envelope.void`,`Void`,{style:`danger`,value:t,confirm:{title:`Void this envelope?`,text:`The signer will no longer be able to sign it. This cannot be undone.`,confirm:`Void envelope`,deny:`Keep`,style:`danger`}}),Su()].filter(e=>e!==!1);return J([i(d.title),...h([x&&{severity:`warning`,title:`The invitation was not delivered`,message:y===`failed`?`The email gave up after repeated failures. Resend invitation queues a fresh email with a new signing link.`:`The invitation was never queued. Resend invitation queues it with a new signing link.`},x&&Eu(e)]),...n.extra??[],...d.personalPurgedAt?[a(`Personal data deleted ${d.personalPurgedAt}${d.recordsPurgedAt?`; signed records deleted`:``} (retention).`)]:[],o([{label:`Status`,value:d.status.replaceAll(`_`,` `)},{label:`Template`,value:`${d.templateId} v${d.templateVersion}`},{label:`Signer`,value:b?`${b.name} <${b.email}>`:d.signer.email},{label:`Signer status`,value:b?.status??`not sent yet`},{label:`Delivery`,value:d.delivery},{label:`Created`,value:d.createdAt},{label:`Sent`,value:d.sentAt??`Not sent`},{label:`Expires`,value:d.expiresAt??`Not set`},{label:`Completed`,value:d.completedAt??`Not completed`},{label:`Document SHA-256`,value:d.docSha256??`Set when sent`},{label:`Final hash`,value:d.finalHash??`Set when completed`}]),...S?[S]:[],g(C),i(`Audit timeline`),l({columns:[c(`seq`,`#`,`number`),c(`event`,`Event`),c(`at`,`When`,`text`),c(`actor`,`By`)],rows:p.items.map(({data:e})=>({seq:e.seq,event:Tu[e.type]??e.type,at:e.at,actor:e.actor})),pageActionId:`audit.page:${t}`,emptyText:`No events yet.`})])}async function Nu(e,t){let n;try{n=await X(e,mu(`envelopes/send`),{id:t})}catch{return J([i(`Envelope`),...h([Z(`The envelope was sent but the invitation could not be queued`,`Open the envelope and use Resend invitation.`)]),g([wu(t)])])}if(n.ok!==!0)return J([i(`Envelope`),...h([Z(`Not sent`,_u(n))]),g([wu(t),Su()])]);let r=n.invitation===`SITE_URL_MISSING`;return J([i(`Envelope`),...h([r?{severity:`warning`,title:`Envelope sent, but no invitation was queued`,message:nr}:xu(`Envelope sent`,`The signer's invitation is queued.`)]),g([wu(t),Su()])])}async function Pu(e,t){let n=await X(e,mu(`envelopes/void`),{id:t});if(n.ok!==!0){let r=n.error?.code===`ENVELOPE_CLOSED`;return Mu(e,t,{extra:h([Z(r?`This envelope cannot be voided`:`Not voided`,r?`It is already completed, declined, voided or expired.`:_u(n))])})}return Mu(e,t,{envelope:n.envelope,invite:`n/a`,extra:h([xu(`Voided`,`The signer can no longer sign this envelope.`)])})}async function Fu(e,t){let n=await X(e,mu(`envelopes/resend`),{id:t});return n.ok===!0?Mu(e,t,{envelope:n.envelope,invite:`queued`,signers:n.signers,extra:h([xu(`Invitation queued`,`A new email with a new signing link is on its way.`)])}):Mu(e,t,{extra:h([n.error?.code===`INVITATION_QUEUED`?xu(`Already queued`,`The invitation is queued or was sent.`):Z(`Not resent`,_u(n,`Only an envelope that is sent and unsigned can be resent.`))])})}const Iu=/^(signer|participant)\./;async function Lu(e,t,n=[]){let r=await X(e,hu(`templates/get`),{id:t}),o=r.template;return r.ok!==!0||!o?J([i(`New envelope`),...h([Z(`Template not found`)]),...n]):J([i(`New envelope: ${o.name}`),...n,a(`Creates a draft you can check before sending it for signature. Signer fields: one per line as key: Label, ending in * when required.`),w({fields:[y(`title`,`Title`,{initialValue:o.name}),y(`signerName`,`Signer name`),y(`signerEmail`,`Signer email`),...o.fields.filter(e=>!Iu.test(e)).map(e=>y(`field:${e}`,e)),y(`signerFields`,`Fields the signer fills in (optional)`,{multiline:!0,placeholder:`phone: Phone number *`})],submit:{label:`Create draft`,actionId:`envelope.create`},blockId:`envelope-new:${t}`}),g([Cu()])])}function Ru(e){return typeof e==`string`?e.slice(0,4e3).split(`
53
+ `).map(e=>e.trim()).filter(e=>e!==``).map(e=>{let t=e.indexOf(`:`),n=(t===-1?e:e.slice(0,t)).trim(),r=t===-1?``:e.slice(t+1).trim(),i=r.endsWith(`*`);return i&&(r=r.slice(0,-1).trim()),{key:n,label:r,...i?{required:!0}:{}}}):[]}async function zu(e,t,n){let r=t?.startsWith(`envelope-new:`)?t.slice(13):``;if(!r)return J(h([Z(`Choose a template first`)]));let i={};for(let[e,t]of Object.entries(n))e.startsWith(`field:`)&&(i[e.slice(6)]=typeof t==`string`?t:``);let a=Y(n.title),o=Ru(n.signerFields),s=await X(e,mu(`envelopes/create`),{templateId:r,...a?{title:a}:{},signer:{name:Y(n.signerName),email:Y(n.signerEmail)},fields:i,...o.length>0?{signerFields:o}:{}});if(s.ok!==!0)return Lu(e,r,h([Z(`Not saved`,_u(s))]));let c=s.envelope.id;return Mu(e,c,{extra:h([xu(`Draft created`,`Check the details, then send it.`)])})}async function Bu(e,t=[]){let n=((await X(e,hu(`templates/list`),{})).templates??[]).map(e=>({name:e.name,id:e.id,version:e.version,fields:(e.fields??[]).join(`, `),integrations:e.integrations===!0?`Yes`:`No`,updated:e.updatedAt,edit:_(`template.edit`,`Edit`,{value:e.id}),use:_(`envelope.new`,`New envelope`,{style:`primary`,value:e.id})}));return J([i(`Templates`),...t,l({columns:[c(`name`,`Name`),c(`id`,`ID`),c(`version`,`Version`,`number`),c(`fields`,`Fields`),c(`integrations`,`Integrations`),c(`updated`,`Updated`,`relative_time`),c(`edit`,``,`element`),c(`use`,``,`element`)],rows:n,pageActionId:`templates.page`,emptyText:`No templates yet. Add one below.`}),i(`New template`),a(`Write the document in Markdown. Use {{field}} for values filled in per envelope, and {{signer.name}} for the signer.`),w({fields:[y(`name`,`Name`),y(`description`,`Description (optional)`),y(`body`,`Template text`,{multiline:!0}),Vu(!1)],submit:{label:`Create template`,actionId:`template.create`}})])}function Vu(e){return S(`integrations`,`Available to integrations`,{description:`Paired sites (such as Events) may send this template for signing.`,initialValue:e})}function Hu(e){let t=Object.fromEntries(In(e).map(e=>[e,`«${e}»`]));try{return Ln(e,t)}catch{return e}}function Uu(e,t,n=[]){let r=String(t.body??``),o=In(r);return J([i(`Edit template: ${String(t.name??``)}`),...n,a(`Version ${String(t.version??1)}. Saving writes a new version; sent envelopes keep the text they were sent with.`),a(`Template id:`),d({code:e}),w({fields:[y(`name`,`Name`,{initialValue:String(t.name??``)}),y(`description`,`Description (optional)`,{initialValue:String(t.description??``)}),y(`body`,`Template text`,{initialValue:r,multiline:!0}),Vu(t.integrations===!0)],submit:{label:`Save new version`,actionId:`template.save`},blockId:`template:${e}`}),i(`Preview`),a(o.length>0?`Fields: ${o.join(`, `)}. Placeholders show as «name».`:`This template has no fields.`),d({code:Hu(r)}),g([_(`envelope.new`,`New envelope from this template`,{style:`primary`,value:e}),_(`template.archive`,`Archive`,{style:`danger`,value:e,confirm:{title:`Archive this template?`,text:`It can no longer be used for new envelopes. Sent envelopes are not affected.`,confirm:`Archive`,deny:`Keep`,style:`danger`}}),Cu()])])}async function Wu(e,t,n=[]){let r=await X(e,hu(`templates/get`),{id:t});return r.ok!==!0||!r.template?Bu(e,h([Z(`Template not found`)])):Uu(t,r.template,n)}async function Gu(e,t){let n=await X(e,hu(`templates/create`),{name:Y(t.name),body:typeof t.body==`string`?t.body:``,...Y(t.description,1e3)?{description:Y(t.description,1e3)}:{},integrations:t.integrations===!0});return n.ok===!0?Bu(e,h([xu(`Template created`)])):Bu(e,h([Z(`Not saved`,_u(n))]))}async function Ku(e,t,n){let r=t?.startsWith(`template:`)?t.slice(9):``;if(!r)return J(h([Z(`Choose a template first`)]));let i={name:Y(n.name),body:typeof n.body==`string`?n.body:``,description:Y(n.description,1e3),integrations:n.integrations===!0},a=await X(e,hu(`templates/update`),{id:r,...i});return a.ok===!0?Uu(r,a.template,h([xu(`Saved`)])):Uu(r,{...i,version:`?`},h([Z(`Not saved`,_u(a))]))}async function qu(e,t){let n=await X(e,hu(`templates/archive`),{id:t});return Bu(e,h([n.ok===!0?xu(`Template archived`):Z(`Not archived`,_u(n))]))}const Ju=[{key:`senderName`,label:`Sender name`,kind:`text`},{key:`expiryDays`,label:`Envelope expiry (days)`,kind:`number`,min:1,max:365},{key:`consentVersion`,label:`Consent version`,kind:`text`},{key:`consentWording`,label:`Consent wording`,kind:`long`},{key:`retentionPersonalDataMonths`,label:`Keep personal data (months)`,kind:`number`,min:1,max:120},{key:`retentionSignedRecordsYears`,label:`Keep signed records (years)`,kind:`number`,min:1,max:50},{key:`turnstileSiteKey`,label:`Turnstile site key`,kind:`text`}],Yu=[{key:`turnstileSecretKey`,label:`Turnstile secret key`},{key:`integrationMasterKey`,label:`Integration master key`}],Xu=e=>typeof e==`string`&&e!==``?`readable`:typeof e==`object`&&e?`unreadable`:`unset`;function Zu(e,t,n=[]){let r=Yu.some(e=>t[e.key]===`unreadable`),o=Jl(null).banner;return J([i(`Settings`),...h([r&&o&&{severity:`error`,title:`Encryption key missing`,message:o.message},t.integrationMasterKey===`unset`&&yu(`Integration master key not set`,`Other plugins cannot create envelopes through the integration protocol until it is saved.`)]),...n,w({fields:[...Ju.map(t=>t.kind===`number`?b(t.key,t.label,{min:t.min,max:t.max,...typeof e[t.key]==`number`?{initialValue:e[t.key]}:{}}):y(t.key,t.label,{multiline:t.kind===`long`,initialValue:typeof e[t.key]==`string`?e[t.key]:``})),...Yu.map(e=>C(e.key,`${e.label} (leave blank to keep)`,{hasValue:t[e.key]===`readable`}))],submit:{label:`Save settings`,actionId:`settings.save`}}),a(`Reminder and one-time-code settings (Pro) are in the plugin's own settings panel.`)])}async function Qu(e){let t=await e.ctx.settings.list(),n=Object.fromEntries(t.map(e=>[e.key,e.value]));return{values:n,secrets:Object.fromEntries(Yu.map(e=>[e.key,Xu(n[e.key])]))}}async function $u(e){let{values:t,secrets:n}=await Qu(e);return Zu(t,n)}async function ed(e,t){let{values:n,secrets:r}=await Qu(e),i=[],a=[];for(let e of Ju){let r=t[e.key];if(r==null||r===``)continue;let o;if(e.kind===`number`){if(o=Number(r),!Number.isInteger(o)||o<(e.min??0)||o>(e.max??2**53-1)){a.push(`${e.label} must be a whole number from ${e.min} to ${e.max}.`);continue}}else o=Y(r,e.kind===`long`?2e3:200);o!==n[e.key]&&i.push([e.key,o])}let o=Yu.filter(e=>Y(t[e.key],500)!==``);if(o.some(e=>e.key===`integrationMasterKey`&&Ul(Y(t[e.key],500)))&&a.push(`The integration master key must be at least 32 characters, or use Generate on the Integrations page.`),a.length>0)return Zu(n,r,h([Z(`Not saved`,a.join(` `))]));if(i.length+o.length>6)return Zu(n,r,h([Z(`Too many changes at once`,`Save at most 6 settings at a time.`)]));if(i.length+o.length===0)return Zu(n,r,h([xu(`Nothing to save`)]));let s={...n},c={...r};try{for(let n of o)await e.ctx.settings.set(n.key,Y(t[n.key],500)),c[n.key]=`readable`;for(let[t,n]of i)await e.ctx.settings.set(t,n),s[t]=n}catch(e){if(!Yl(e))throw e;let t=Jl(null).banner;return Zu(n,r,h([{severity:`error`,title:`Encryption key missing`,message:t?.message}]))}return Zu(s,c,h([xu(`Saved`)]))}const td=e=>Y(e,200);async function nd(e,t){if(t.type===`page_load`)switch(t.page){case`/envelopes`:return Ou(e,``);case`/templates`:return Bu(e);case`/settings`:return $u(e);case`/integrations`:return uu(e);default:return J(h([Z(`Page not found`)]))}if(t.type===`form_submit`){let n=t.values;switch(t.action_id){case`envelopes.filter`:return Ou(e,Y(n.status));case`envelope.create`:return zu(e,t.block_id,n);case`template.create`:return Gu(e,n);case`template.save`:return Ku(e,t.block_id,n);case`settings.save`:return ed(e,n);case`client.create`:return fu(e,n);case`retention.preview`:return Au(e,Y(n.subject),!1)}}else{let n=td(t.value);if(t.action_id.startsWith(`envelopes.page:`))return Ou(e,t.action_id.slice(15),[],Y(t.value,500)||void 0);if(t.action_id.startsWith(`audit.page:`))return Mu(e,td(t.action_id.slice(11)));switch(t.action_id){case`envelopes.back`:case`envelopes.page`:return Ou(e,``);case`envelope.open`:return Mu(e,n);case`envelope.send`:return Nu(e,n);case`envelope.void`:return Pu(e,n);case`envelope.resend`:return Fu(e,n);case`retention.erase`:return Au(e,n,!0);case`envelope.new`:return Lu(e,n);case`integrations.generate-key`:return du(e);case`client.revoke`:return pu(e,n);case`clients.page`:return uu(e);case`templates.back`:case`templates.page`:return Bu(e);case`template.edit`:return Wu(e,n);case`template.archive`:return qu(e,n)}}return J(h([Z(`Unknown action`)]))}const rd={admin:{handler:(async(e,t)=>{let n=`http://localhost`;try{n=new URL(e.request?.url??``).origin}catch{}return nd({ctx:t,origin:n,now:Date.now(),user:e.user??null},e.input)})}},id=[`completed`,`declined`,`voided`,`expired`],ad=e=>{if(!e)return;let t=Date.parse(e);return Number.isNaN(t)?void 0:Math.floor(t/1e3)};function od(e,t){let{status:n,clientId:r,externalRef:i}=t;if(!id.includes(n)||!r||!i||t.docSha256===null)return;let a=n===`completed`,o=a?ad(t.completedAt):ad(t.closedAt)??ad(t.updatedAt);if(o===void 0)return;let s={v:1,typ:`receipt`,cid:r,envelopeId:e,ref:i,status:n,docSha256:t.docSha256,pdfSha256:a?t.pdfSha256??null:null,finalHash:a?t.finalHash:null,at:o};return Ye(`receipt`,s).ok?s:void 0}async function sd(e,t,n){let r=od(e,t);return r?dt(`receipt`,r,n):void 0}function cd(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`):void 0}function ld(e){let t={};return{settings:()=>t,async getClient(n){let[r,i]=await Promise.all([e.settings.list(),B(e).clients.get(n)]);t=Object.fromEntries(r.map(e=>[e.key,e.value]));let a=ml(t.integrationMasterKey);if(!(!a||!i))return{secret:await Lt(a,n),revoked:i.revokedAt!==void 0&&i.revokedAt!==null,returnUrlAllowlist:cd(i.returnUrlAllowlist)}}}}async function ud(e,t,n){let r=ml(n);if(!(!r||!t.clientId))return sd(e,t,await Lt(r,t.clientId))}async function dd(e,t,n=Date.now()){let r=await ut({token:V(e).request,now:n,getClient:ld(t).getClient});if(!r.ok)return U(r.error);let i=[],a;for(let e=0;e<3;e++){let e=await B(t).templates.query({where:{status:`active`},limit:200,...a===void 0?{}:{cursor:a}});if(i.push(...e.items),!e.hasMore||!e.cursor)break;a=e.cursor}return{ok:!0,templates:i.filter(e=>Fr(e.data)).map(e=>({id:e.id,name:e.data.name,version:e.data.version})).sort((e,t)=>e.name<t.name?-1:e.name>t.name?1:e.id<t.id?-1:1)}}const fd=(e,t)=>dd(e.input,t),pd=[`sent`,`in_progress`];function md(e){let t=V(e).token;return typeof t==`string`&&t.length>0&&t.length<=200?t:null}const hd=e=>({...e.requestMeta?.ip?{ip:e.requestMeta.ip}:{},...e.requestMeta?.userAgent?{ua:e.requestMeta.userAgent}:{}});function gd(e){try{return e!==void 0&&new URL(e.url).searchParams.has(`token`)}catch{return!1}}function _d(e,t){let n=new Map,r,i={get:t=>{let r=n.get(t);return r||(r=e.kv.get(t),n.set(t,r)),r},set:async(e,t)=>{r={key:e,value:t}}},a=Date.now(),o=()=>Sn(i,t.requestMeta?.ip??`unknown`,a,{scope:`ceremony`,limit:20,windowSeconds:600,salt:`esign-ceremony/1`});return{async blocked(){return!(await o()).ok},async fail(){let t=await o();return t.ok&&r&&await e.kv.set(r.key,r.value),U(t.ok?`SIGNING_TOKEN_INVALID`:`RATE_LIMITED`)}}}async function vd(e,t){let{items:n}=await B(e).signers.query({where:{tokenHash:await j(t)},limit:1}),r=n[0];return r&&await he(t,r.data.tokenHash)?r:null}async function yd(e,t){let{items:n}=await B(e).signers.query({where:{copyTokenHash:await j(t)},limit:1}),r=n[0];return r?.data.copyTokenHash&&await he(t,r.data.copyTokenHash)?r:null}const bd=e=>!!(e.returnUrl&&e.clientId),xd=(e,t)=>bd(t)?e.settings.get(`integrationMasterKey`):Promise.resolve(void 0);async function Sd(e,t,n){if(!t.returnUrl)return{};let r=await ud(e,t,n);return{returnUrl:t.returnUrl,...r?{receipt:r}:{}}}const Cd=(e,t)=>e.find(e=>e.key===t)?.value;async function wd(e,t){let n=await(t?e.settings.list():e.settings.list(`consent`)),r=(e,t)=>{let r=Cd(n,e);return typeof r==`string`&&r.length>0?r:t},i=r(`consentWording`,`I agree to use electronic records and an electronic signature for this document.`);return{version:r(`consentVersion`,`1`),wording:i,sha256:await F(i),masterKey:Cd(n,`integrationMasterKey`)}}const Td=(e,t)=>e.expiresAt!==null&&e.expiresAt<=t,Ed=(e,t)=>e.signerIds.length>1?t.order:void 0;async function Dd(e,t,n,r,i){let a=B(e).audit_events,o=i;for(let e=0;e<2;e++){if(o??=await hr(t,await _r(a,t),r,n),await vr(a,o))return o;o=void 0}throw Error(`audit chain contention`)}async function Od(e,t){if(gd(e.request))return U(`TOKEN_IN_QUERY`);let n=_d(t,e),r=md(e.input);if(r===null)return n.fail();if(await n.blocked())return U(`RATE_LIMITED`);let i=V(e.input).open===!0,{envelopes:a,snapshots:o}=B(t),s=await vd(t,r),c=s?null:await yd(t,r),l=s??c;if(!l)return n.fail();let u=await a.get(l.data.envelopeId);if(!u)return U(`ENVELOPE_NOT_FOUND`);if(c&&u.status!==`completed`)return n.fail();if(!pd.includes(u.status)||l.data.status!==`pending`){let e={ok:!0,state:`closed`,status:u.status,title:u.title,...c?{}:await Sd(l.data.envelopeId,u,await xd(t,u))};return u.status!==`completed`||l.data.status!==`signed`?e:u.pdfSha256?{...e,pdf:`ready`,download:await ca(t,l.data.envelopeId,Date.now())}:{...e,pdf:`pending`}}let d=N();if(Td(u,d))return U(`SIGNING_TOKEN_EXPIRED`);let f=u.document,[p,m]=await Promise.all([u.snapshot?o.getMany(u.snapshot.ids):Promise.resolve(new Map),wd(t,!1)]),h=f&&!u.snapshot?``:ii([...p.values()]);if(h===null)return U(`INTERNAL`);let g=u.status,_=Ed(u,l.data);if(i){let n=!1;if(u.status===`sent`&&(n=(await kr(a,l.data.envelopeId,`sent`,`in_progress`,{updatedAt:d})).ok,n&&(g=`in_progress`)),_!==void 0&&(n=(await B(t).signers.updateIf(l.id,{where:{viewedAt:null},set:{viewedAt:d}})).applied),n){let n=Ka(d,u.docSha256??``,hd(e),_);if(!(await gr(B(t).audit_events,l.data.envelopeId,n,{salt:u.piiSalt})).ok)throw Error(`audit chain contention`)}}let{participant:v}=l.data;return{ok:!0,state:`ready`,envelope:{id:l.data.envelopeId,title:u.title,status:g,docSha256:u.docSha256,expiresAt:u.expiresAt},signer:{name:l.data.name,as:l.data.as,...v?{participant:v.name}:{}},snapshot:h,...f?{document:{kind:f.kind,name:f.name,bytes:f.bytes,pages:f.pages}}:{},...u.otp?{otp:l.data.otpVerifiedAt?`verified`:`required`}:{},...u.signerFields?.length?{fields:u.signerFields}:{},consent:{version:m.version,wording:m.wording,sha256:m.sha256}}}async function kd(e,t,n){if(gd(e.request))return U(`TOKEN_IN_QUERY`);let r=_d(t,e),i=md(e.input);if(i===null)return r.fail();let a=Va(e.input);if(!a.ok)return H(a.error);let{envelopes:o,signers:s,audit_events:c}=B(t),l=await vd(t,i);if(!l||l.data.status!==`pending`)return r.fail();let u=l.data.envelopeId,d=await o.get(u);if(!d)return U(`ENVELOPE_NOT_FOUND`);if(d.status===`sent`)return U(`SESSION_REQUIRED`);if(d.status!==`in_progress`||d.document&&!n)return U(`ENVELOPE_CLOSED`);let f=N();if(Td(d,f))return U(`SIGNING_TOKEN_EXPIRED`);if(d.otp&&!l.data.otpVerifiedAt)return U(`OTP_REQUIRED`);if(d.docSha256===null||a.value.docSha256!==d.docSha256)return H([{path:`docSha256`,code:`DOC_CHANGED`}]);let p=await wd(t,bd(d));if(a.value.consentSha256!==p.sha256)return H([{path:`consentSha256`,code:`CONSENT_CHANGED`}]);let m=d.signerFields??[],h=a.value.fieldValues,g=[...Object.keys(h).filter(e=>!m.some(t=>t.key===e)).map(e=>({path:`fieldValues.${e}`,code:`INVALID_FIELDS`})),...m.filter(e=>e.required&&(h[e.key]??``).trim()===``).map(e=>({path:`fieldValues.${e.key}`,code:`INVALID_FIELDS`}))];if(g.length>0)return H(g);let _=await Ua(d.docSha256,a.value.signature,{fieldValues:h,salt:d.piiSalt}),v=hd(e),y={status:`signed`,signature:_,consentAt:f,consentVersion:p.version,consentSha256:p.sha256,signedAt:f,fieldValues:h,...v};if(d.signerIds.length>1)return n?n(t,{envelopeId:u,envelope:d,signer:l,set:y,now:f}):U(`ENVELOPE_CLOSED`);let b=qa({at:f,docSha256:d.docSha256,consentVersion:p.version,consentSha256:p.sha256,signature:_,signerName:l.data.name,who:v}),x=await hr(u,await _r(c,u),b,d.piiSalt),S=await Sr(d.docSha256,x.at(-1)?.data.hash??``),C=await kr(o,u,d.status,`completed`,{completedAt:f,finalHash:S,updatedAt:f});if(!C.ok)return U(`ENVELOPE_CLOSED`);if(await s.updateIf(l.id,{where:{status:`pending`},set:y}),!await vr(c,x))throw Error(`audit chain contention`);return await $i(t.cron,u,Date.parse(f)),{ok:!0,status:`completed`,completedAt:f,...await Sd(u,C.value,p.masterKey)}}async function Ad(e,t){if(gd(e.request))return U(`TOKEN_IN_QUERY`);let n=_d(t,e),r=md(e.input);if(r===null)return n.fail();let i=Ha(V(e.input).reason);if(i===null)return H([{path:`reason`,code:`INVALID_INPUT`}]);let{envelopes:a,signers:o}=B(t),s=await vd(t,r);if(!s||s.data.status!==`pending`)return n.fail();let c=s.data.envelopeId,l=await a.get(c);if(!l)return U(`ENVELOPE_NOT_FOUND`);if(!Dr(l.status,`declined`))return U(`ENVELOPE_CLOSED`);let u=N();if(Td(l,u))return U(`SIGNING_TOKEN_EXPIRED`);let d=await kr(a,c,l.status,`declined`,{closedAt:u,updatedAt:u});if(!d.ok)return U(`ENVELOPE_CLOSED`);let f=hd(e);return await o.updateIf(s.id,{where:{status:`pending`},set:{status:`declined`,declinedAt:u,...i===void 0?{}:{declineReason:i},...f}}),await Dd(t,c,l.piiSalt,Ja({at:u,docSha256:l.docSha256,hasReason:i!==void 0,who:f,order:Ed(l,s.data)})),{ok:!0,status:`declined`,...await Sd(c,d.value,await xd(t,d.value))}}const jd=e=>(t,n)=>e(t,n),Md=e=>({"public/session":jd(Od),"public/submit":jd((t,n)=>kd(t,n,e)),"public/decline":jd(Ad)}),Nd=Md();function Pd(e){try{return new URL(e.site.url).origin}catch{return}}async function Fd(e,t,n={}){let r=(n.now??Date.now)(),i=N(r),{envelopes:a,signers:o,snapshots:s,templates:c,nonces:l}=B(t),u=ld(t),d=await st({token:V(e).intent,now:r,getClient:u.getClient,consumeNonce:async(e,t,n)=>{let r=`${e}.${t}`;try{let t={nonce:r,cid:e,expiresAt:N(n*1e3)};return(await l.compareAndSet(r,null,t)).applied}catch(e){if(ga(e))return!1;throw e}},siteOrigin:Pd(t)});if(!d.ok)return U(d.error);let f=d.value,p=u.settings();if(f.replace===!0)return zd(t,f,i);let m=f.tplVersion===void 0?void 0:R(f.tpl,f.tplVersion),h=await c.getMany(m===void 0?[f.tpl]:[f.tpl,m]),g=h.get(f.tpl);if(!Fr(g))return U(`TEMPLATE_NOT_FOUND`);let _=Jr(g,m===void 0?void 0:h.get(m),f.tplVersion);if(!_.ok)return U(`TEMPLATE_NOT_FOUND`);let v=cr(n.random),y=$r(f,_.value,{now:i,piiSalt:v});if(!y.ok)return H(y.error);let b={delivery:y.value.delivery,signer:y.value.signer},x=f.resend===!0?(e,n,i)=>rr(t,{signerId:e,envelope:n,token:i,senderSetting:p.senderName,now:r}):void 0,S=A(n.random),C=await j(S),ee=async e=>{let t=await ci(f.cid,f.ref,e);return{id:t,sent:await ai(t,y.value,_.value,{now:i,tokenHash:C,expiryDays:ha(p.expiryDays)})}},w=await ee(1);if(!w.sent.ok)return Array.isArray(w.sent.error)?H(w.sent.error):U(`INTERNAL`);let T=await a.compareAndSet(w.id,null,w.sent.value.envelope);if(!T.applied){let e=await a.query({where:{clientId:f.cid,externalRef:f.ref},limit:100}),i=si(e.items);if(i)return i.data.status===`draft`&&await _l(t.cron,i.id,r),Rd(o,i.id,i.data,b,n.random,x);let s=Math.max(e.items.length,1)+1;if(y.value.delivery===`email`){let e=await ci(f.cid,f.ref,s);if(!(await a.compareAndSet(e,null,y.value)).applied){let t=await a.get(e);return t?Rd(o,e,t,b,n.random):U(`INTERNAL`)}return await _l(t.cron,e,r),Id(e,y.value,void 0)}if(w=await ee(s),!w.sent.ok)return Array.isArray(w.sent.error)?H(w.sent.error):U(`INTERNAL`);if(T=await a.compareAndSet(w.id,null,w.sent.value.envelope),!T.applied){let e=await a.get(w.id);return e?Rd(o,w.id,e,b,n.random):U(`INTERNAL`)}}let{id:E,sent:D}=w;if(!D.ok)return U(`INTERNAL`);await s.putMany(D.value.chunks);let te=await va(o,D.value.signer,S,n.random);D.value.envelope.delivery===`email`&&await rr(t,{signerId:D.value.signer.id,envelope:D.value.envelope,token:te,senderSetting:p.senderName,now:r});let O=[li(y.value,`integration`),ui(D.value.envelope,`integration`)];return await B(t).audit_events.putMany(await mr(E,O,v)),Id(E,D.value.envelope,te)}function Id(e,t,n,r=t.delivery===`inline`){return{ok:!0,envelopeId:e,status:t.status,...n!==void 0&&r?{signingToken:n}:{}}}function Ld(e,t){let n=e.signer;return n.email===t.email&&n.as===t.as&&(n.participant?.name??null)===(t.participant?.name??null)}async function Rd(e,t,n,r,i,a){let o=n.signerIds[0],s=(n.status===`sent`||n.status===`in_progress`)&&Ld(n,r.signer),c=r.delivery===`inline`&&s,l=a!==void 0&&r.delivery===`email`&&n.delivery===`email`&&s;if(!c&&!l||o===void 0)return Id(t,n,void 0);let u=await _a(A(i),i,t=>e.updateIf(o,{where:{status:`pending`},set:{tokenHash:t}}));if(!u.value.applied)return Id(t,n,void 0);if(c||!a)return Id(t,n,u.token,!0);let d=await a(o,n,u.token);return{...Id(t,n,void 0),...d?{resent:!0}:{}}}async function zd(e,t,n){let{envelopes:r}=B(e),i=si((await r.query({where:{clientId:t.cid,externalRef:t.ref},limit:100})).items);if(!i)return{ok:!0,status:`none`};let a=i.data.signer;if(a.name===t.signer.name.trim()&&a.email===t.signer.email.trim().toLowerCase()&&a.as===(t.as??`self`)&&(a.participant?.name??null)===(t.participant?.name.trim()??null)||i.data.status===`completed`)return Id(i.id,i.data,void 0);let o=await kr(r,i.id,i.data.status,`voided`,{closedAt:n,updatedAt:n});return o.ok?(await xa(e,i.id,o.value,{type:`envelope.voided`,at:n,actor:`integration`}),Id(i.id,o.value,void 0)):U(`ENVELOPE_CLOSED`)}const Bd=(e,t)=>Fd(e.input,t),Vd=`integrations:site-client`,Hd=[`origin`,`sec-fetch-mode`,`sec-fetch-site`,`sec-fetch-dest`],Ud={ADMIN_REQUIRED:`Only an administrator can pair plugins.`,SERVER_ONLY:`Pairing runs on the server only.`,BAD_REQUEST:`The request was not valid.`,MASTER_KEY_INVALID:`The integration master key is unreadable or shorter than 32 characters.`,ENCRYPTION_KEY_MISSING:`EMDASH_ENCRYPTION_KEY is not set, so the master key cannot be saved.`},Wd=e=>({ok:!1,error:{code:e,message:Ud[e]}});function Gd(e,t){if(e)return typeof e.get==`function`?e.get(t)??void 0:e[t]}const Kd=e=>e!=null&&e!==``,qd={"integrations/pair":{handler:(async(e,t)=>{let n=e.user?.role;if(typeof n!=`number`||n<50)return Wd(`ADMIN_REQUIRED`);if(Hd.some(t=>Gd(e.request?.headers,t)!==void 0))return Wd(`SERVER_ONLY`);let r=V(e.input),i=r.action;if(i!==`status`&&i!==`pair`&&i!==`unpair`)return Wd(`BAD_REQUEST`);let a=r.clientId;if(a!==void 0&&(typeof a!=`string`||!Ce.test(a)))return Wd(`BAD_REQUEST`);let o=B(t).clients,[s,c]=await Promise.all([t.settings.list(),t.kv.get(Vd)]),l=typeof c==`string`?c:null,u=typeof a==`string`?a:l,[d,f]=await Promise.all([u?o.get(u):null,l&&l!==u&&i!==`status`?o.get(l):null]),p=d!==null&&!d.revokedAt,m=f!==null&&!f.revokedAt,h=N();if(i===`status`)return d&&u?{ok:!0,client:p?`active`:`revoked`,clientId:u}:{ok:!0,client:`none`};if(i===`unpair`)return m&&l&&await Kl(o,l,h),{ok:!0,revoked:p&&u?await Kl(o,u,h):!1};let g=s.find(e=>e.key===`integrationMasterKey`)?.value;if(!Kd(g)){g=Hl();try{await t.settings.set(`integrationMasterKey`,g)}catch(e){if(Yl(e))return Wd(`ENCRYPTION_KEY_MISSING`);throw e}}let _=ml(g);if(!_)return Wd(`MASTER_KEY_INVALID`);let v=p&&u?u:m?l:null;if(v)return v!==l&&(await t.kv.set(Vd,v),m&&l&&await Kl(o,l,h)),{ok:!0,created:!1,clientId:v,pairing:It(v,await Lt(_,v))};let y=await Gl(o,{name:`Events on this site`,returnUrlAllowlist:[],masterKey:g},{now:h});return y.ok?(await t.kv.set(Vd,y.client.clientId),{ok:!0,created:!0,clientId:y.client.clientId,pairing:y.pairing}):Wd(`MASTER_KEY_INVALID`)})}},Jd=64*1024,Yd=[{name:`public/envelopes/from-intent`,methods:[`POST`],body:`json`,maxBytes:16*1024},{name:`public/session`,methods:[`POST`],body:`json`,maxBytes:8*1024},{name:`public/otp/send`,methods:[`POST`],body:`json`,maxBytes:8*1024},{name:`public/otp/verify`,methods:[`POST`],body:`json`,maxBytes:8*1024},{name:`public/submit`,methods:[`POST`],body:`json`,maxBytes:256*1024},{name:`public/decline`,methods:[`POST`],body:`json`,maxBytes:8*1024},{name:`public/download`,methods:[`GET`],body:`none`,response:`raw`},{name:`public/verify`,methods:[`POST`],body:`json`,maxBytes:8*1024},{name:`public/receipts/lookup`,methods:[`POST`],body:`json`,maxBytes:8*1024},{name:`public/templates/catalog`,methods:[`POST`],body:`json`,maxBytes:Jd},{name:`public/self-serve/start`,methods:[`POST`],body:`json`,maxBytes:Jd}];async function Xd(){return oe({code:`NOT_FOUND`}).body}function Zd(e={}){let t={};for(let n of Yd)t[n.name]={public:!0,methods:[...n.methods],request:n.maxBytes===void 0?{body:n.body}:{body:n.body,maxBytes:n.maxBytes},...n.response?{response:n.response}:{},handler:e[n.name]??Xd};return t}const Qd=e=>Number(/_(\d+)$/.exec(e)?.[1]??0);function $d(e){let t;for(let n of e)(!t||Qd(n.id)>Qd(t.id)||Qd(n.id)===Qd(t.id)&&n.data.createdAt>t.data.createdAt)&&(t=n);return t}async function ef(e,t,n=Date.now()){let r=ld(t),i=await lt({token:V(e).request,now:n,getClient:r.getClient});if(!i.ok)return U(i.error);let{cid:a,ref:o}=i.value,s=$d((await B(t).envelopes.query({where:{clientId:a,externalRef:o},limit:100})).items.filter(e=>e.data.clientId===a&&e.data.externalRef===o));if(!s)return{ok:!0,state:`none`,receipt:null};if(!Or(s.data.status))return{ok:!0,state:`pending`,receipt:null};let c=await ud(s.id,s.data,r.settings().integrationMasterKey);return c?{ok:!0,state:`terminal`,receipt:c}:U(`INTERNAL`)}const tf=(e,t)=>ef(e.input,t),nf=/^[0-9a-f]{64}$/,rf=async(e,t)=>{let n=V(e.input).sha256,r=typeof n==`string`?n.toLowerCase():``;if(!nf.test(r))return H([{path:`sha256`,code:`invalid`}]);if(!(await Sn({get:e=>t.kv.get(e),set:(e,n)=>t.kv.set(e,n)},e.requestMeta?.ip??`unknown`,Date.now(),{scope:`esign-verify`,limit:20,windowSeconds:600,salt:`esign-verify/1`})).ok)return U(`RATE_LIMITED`);let{envelopes:i,audit_events:a}=B(t),o=(await i.query({where:{pdfSha256:r},limit:1})).items[0];if(!o||o.data.status!==`completed`)return{ok:!0,matched:!1};let s=o.data,{items:c}=await a.query({where:{envelopeId:o.id},orderBy:{seq:`asc`},limit:101}),l=null;if(c.length<=100){let e=c.map(e=>e.data),t=await br(o.id,e);l=t.ok&&s.docSha256!==null&&e.at(-1)?.type===`envelope.completed`&&await Sr(s.docSha256,t.value.head)===s.finalHash}return{ok:!0,matched:!0,status:s.status,completedAt:s.completedAt,finalHash:s.finalHash,chainVerified:l}},af=[{name:er,schedule:`* * * * *`},{name:xl,schedule:`0 * * * *`},{name:Tl,schedule:`23 3 * * *`},{name:dl,schedule:`17 * * * *`}],of=Zd({"public/envelopes/from-intent":Bd,"public/download":fa,"public/verify":rf,"public/receipts/lookup":tf,"public/templates/catalog":fd,...Nd}),sf={hooks:{"plugin:activate":async(e,t)=>{await Dn(t,af)},cron:async(e,t)=>{await kn(e,t,af,Date.now())||await ar(e,t)||await Fa(e,t)||await bl(e,t)||await wl(e,t)||await Ll(e,t)||await pl(e,t)||await ta(e,t)}},routes:{...of,...rd,...ru,...Aa,...qd,admin:jn(rd.admin,An),"templates/create":jn(ru[`templates/create`]),"public/verify":jn(of[`public/verify`])}},cf={publicKey:`Trv2FjPQUPvm0izcO5IyqAZ5hse1-WShywKnN2s3ijg`,product:`esign`,buildDate:`2026-11-02`},lf=`esign-route-`,uf=e=>`${lf}${e}`;function df(e,t,n,r=0){return e.cron?.schedule(uf(t),{schedule:N(n),data:{envelopeId:t,attempt:r}})}const ff=async(e,{envelopeId:t,envelope:n,signer:r,set:i,now:a})=>{let{signers:o}=B(e);if(n.routing===`sequential`&&r.data.order>1){let e=await o.getMany(n.signerIds);if(!Ps(`sequential`,r.data,[...e.values()]))return U(`SIGNING_OUT_OF_TURN`)}return(await o.updateIf(r.id,{where:{status:`pending`},set:i})).applied?(await df(e,t,Date.parse(a)),{ok:!0,status:`in_progress`,signedAt:a}):U(`ENVELOPE_CLOSED`)};async function pf(e,t,n,r=0){let{envelopes:i,signers:a,audit_events:o}=B(e),s=await i.get(t);if(!s||s.signerIds.length<2||s.status===`completed`||s.personalPurgedAt)return`skipped`;let[c,l]=await Promise.all([a.getMany(s.signerIds),o.query({where:{envelopeId:t},orderBy:{seq:`asc`},limit:100})]),u=s.signerIds.flatMap(e=>{let t=c.get(e);return t?[{id:e,data:t}]:[]}),d=N(n),f=L(e),p=zs(s,u,l.items.map(e=>e.data),d),m=f?p.invite:void 0,h=m||!p.invite?p.inputs:p.inputs.filter(e=>e.type!==`signer.invited`);if(h.length===0&&!m)return`idle`;if(l.hasMore)return e.log.error(`several-signer envelope has too many audit events to route`,{envelopeId:t}),`gave-up`;let g=await hr(t,l.items.at(-1)?.data??null,h,s.piiSalt),_=async()=>r+1>=5?(e.log.error(`several-signer envelope not routed: the chain never settled`,{envelopeId:t}),`gave-up`):(await df(e,t,n+6e4,r+1),`retry`);if(p.complete){let r=await Sr(s.docSha256??``,g.at(-1)?.data.hash??``);if(!(await kr(i,t,s.status,`completed`,{completedAt:d,finalHash:r,updatedAt:d})).ok)return _();if(!await vr(o,g))throw Error(`audit chain contention`);return await $i(e.cron,t,n),`completed`}return g.length>0&&!await vr(o,g)?_():m?(await mf(e,s,m,f,n),`invited`):`audited`}async function mf(e,t,n,r,i){let a=N(i),o=await e.settings.get(`senderName`),s=await _a(A(),void 0,t=>B(e).signers.updateIf(n,{where:{status:`pending`,waiting:!0},set:{tokenHash:t,invitedAt:a,waiting:!1}}));if(!s.value.applied)return;let{email:c,name:l}=s.value.data;await I(e).put(Us(n),Ws(Qn({to:c,signerName:l,title:t.title,sender:tr(e,o),link:`${r}/sign/${s.token}`,expiresAt:t.expiresAt}),i))}async function hf(e,t){if(!e.name.startsWith(lf))return!1;let n=e.data?.envelopeId,r=e.data?.attempt;return typeof n==`string`&&n.length>0&&await pf(t,n,Date.now(),typeof r==`number`&&Number.isSafeInteger(r)?r:0),!0}const gf=`reminders`,_f=`reminders-more`;function vf(e,t){let n=t.find(e=>e.status!==`signed`);return e.routing===`sequential`&&n?.waiting===!0&&Ps(`sequential`,n,t)}async function yf(e,t,n,r){let i=L(e);if(!i)return;let a=await e.settings.list(),o=e=>a.find(t=>t.key===e)?.value,s=o(`licenceKey`);if(!ce(await t.check({settings:{get:async()=>s},site:e.site}),`new`).ok)return;let c=Bs(o(`reminderCadenceDays`)),{envelopes:l,signers:u}=B(e),d=await l.query({where:{status:{in:[`sent`,`in_progress`]},expiresAt:{gt:N(n)}},orderBy:{expiresAt:`asc`},limit:50,...r?{cursor:r}:{}}),f=d.items.filter(e=>Date.parse(e.data.sentAt??``)+c*864e5<=n),p=f.flatMap(e=>e.data.signerIds),m=p.length>0?await u.getMany(p):new Map,h=e=>e.data.signerIds.flatMap(e=>{let t=m.get(e);return t?[{id:e,data:t}]:[]}),[g,..._]=f.flatMap(e=>h(e).filter(t=>Vs(e.data,t.data,{now:n,cadenceDays:c})).map(t=>({envelope:e,signer:t})));if(g)await bf(e,g.envelope,g.signer,i,o(`senderName`),n);else{let t=f.find(e=>vf(e.data,h(e).map(e=>e.data)));t&&await df(e,t.id,n)}if(_.length>0||d.hasMore&&d.cursor){let t=_.length>0?r:d.cursor;await e.cron?.schedule(_f,{schedule:N(n+6e4),...t?{data:{cursor:t}}:{}})}}async function bf(e,t,n,r,i,a){let{signers:o,audit_events:s}=B(e),c=N(a),l=(n.data.reminders??0)+1,u=await _a(A(),void 0,e=>o.updateIf(n.id,{where:{status:`pending`,tokenHash:n.data.tokenHash},set:{tokenHash:e,remindedAt:c,reminders:l}}));if(!u.value.applied)return!1;if(await I(e).put(Us(n.id),Ws(Hs({to:n.data.email,signerName:n.data.name,title:t.data.title,sender:tr(e,i),link:`${r}/sign/${u.token}`,expiresAt:t.data.expiresAt}),a)),!(await gr(s,t.id,Is(n.data,c,l),{salt:t.data.piiSalt})).ok)throw Error(`audit chain contention`);return!0}async function xf(e,t,n,r=Date.now()){if(e.name===Tn)return await t.cron?.schedule(gf,{schedule:`29 * * * *`}),!1;if(e.name!==gf&&e.name!==_f)return!1;let i=e.name===_f?e.data?.cursor:void 0;return await yf(t,n,r,typeof i==`string`&&i.length>0?i:void 0),!0}const Sf=`mcp-send-`,Cf=e=>(sf.routes??{})[e].handler,wf=e=>typeof e==`object`&&e&&!Array.isArray(e)?e:{},Tf=()=>({ok:!1,error:{code:`SITE_URL_MISSING`,message:nr}});async function Ef(e,t){let{signers:n,routing:r,...i}=wf(e.input);if(!Array.isArray(n)||n.length<1||n.length>10)return H([{path:`signers`,code:`INVALID_SIGNERS`}]);if(n.length>1)return Ks({...e,input:{...i,signers:n,routing:r??`parallel`}},t);if(!L(t))return Tf();let a=await Cf(`envelopes/create`)({...e,input:{...i,signer:n[0]}},t);if(!a.envelope)return a;let o=e.user?.id;return await t.cron?.schedule(`${Sf}${a.envelope.id}`,{schedule:N(),data:{envelopeId:a.envelope.id,...typeof o==`string`?{userId:o}:{}}}),{...a,sending:!0}}async function Df(e,t){if(!e.name.startsWith(Sf))return!1;let n=e.data?.userId;return await Cf(`envelopes/send`)({input:{id:e.name.slice(9)},...typeof n==`string`?{user:{id:n}}:{}},t),!0}async function Of(e,t){let{snapshot:n,...r}=wf(await Cf(`envelopes/get`)(e,t));return r}async function kf(e,t){let n=wf(e.input).id;if(typeof n!=`string`||n.length===0||n.length>100)return H([{path:`id`,code:`INVALID_INPUT`}]);let r=L(t);if(!r)return Tf();let{envelopes:i,signers:a}=B(t),o=await i.get(n);if(!o)return U(`ENVELOPE_NOT_FOUND`);if(o.status!==`sent`&&o.status!==`in_progress`)return U(`ENVELOPE_CLOSED`);let s=Date.now(),c=await a.getMany(o.signerIds),[l,...u]=o.signerIds.flatMap(e=>{let t=c.get(e);return t&&Vs(o,t,{now:s,cadenceDays:.041666666666666664})?[{id:e,data:t}]:[]});return l?await bf(t,{id:n,data:o},l,r,await t.settings.get(`senderName`),s)?{ok:!0,reminded:{signer:l.data.order},remaining:u.length}:{ok:!1,error:{code:`SIGNER_CHANGED`,message:`The signer's status changed. Try again.`}}:{ok:!1,error:{code:`NOTHING_TO_REMIND`,message:`No signer is due a reminder: each has signed, is not yet invited, was emailed in the last hour or has had the most reminders.`}}}const Af=e=>({permission:`plugins:manage`,handler:e});function jf(e){return{"pro/mcp/templates":Af(Cf(`templates/list`)),"pro/mcp/send":e.gate(`esign/envelope-send`,Af(Ef)),"pro/mcp/status":Af(Of),"pro/mcp/remind":e.gate(`new`,Af(kf)),"pro/mcp/void":Af(Cf(`envelopes/void`))}}const Mf=[`sent`,`in_progress`],Nf=(e,t,n={})=>({ok:!1,error:{code:e,message:t,...n}}),Pf=(e,t)=>typeof e==`object`&&e?e[t]:void 0;function Ff(e){let t=Pf(e,`token`);return typeof t==`string`&&t.length>0&&t.length<=200?t:null}function If(e){try{return e!==void 0&&new URL(e.url).searchParams.has(`token`)}catch{return!1}}async function Lf(e,t,n,r,i){return!(await Sn({get:t=>e.kv.get(t),set:(t,n)=>e.kv.set(t,n)},t.requestMeta?.ip??`unknown`,i,{scope:n,limit:r,windowSeconds:600,salt:`esign-otp/1`})).ok}async function Rf(e,t,n){let{signers:r,envelopes:i}=B(e),a=(await r.query({where:{tokenHash:await j(t)},limit:1})).items[0];if(!a||a.data.status!==`pending`||!await he(t,a.data.tokenHash))return{error:U(`SIGNING_TOKEN_INVALID`)};let o=a.data.envelopeId,s=await i.get(o);return s?Mf.includes(s.status)?s.expiresAt!==null&&s.expiresAt<=n?{error:U(`SIGNING_TOKEN_EXPIRED`)}:s.otp?{signer:{id:a.id,data:a.data},envelope:s,envelopeId:o}:{error:Nf(`OTP_NOT_REQUIRED`,`This document does not need a code.`)}:{error:U(`ENVELOPE_CLOSED`)}:{error:U(`ENVELOPE_NOT_FOUND`)}}const zf=e=>`Your code to sign: ${e.title}`,Bf=e=>`Your one-time code is ${e}\n\nIt expires in ${mo/6e4} minutes. Enter it on the signing page to continue. If you did not ask for it, ignore this email; nobody can sign for you without it. Never share this code.`;async function Vf(e,t){if(If(e.request))return U(`TOKEN_IN_QUERY`);let n=Ff(e.input);if(n===null)return H([{path:`token`,code:`INVALID_INPUT`}]);let r=Date.now();if(await Lf(t,e,`otp-send`,10,r))return U(`RATE_LIMITED`);let i=await Rf(t,n,N(r));if(i.error)return i.error;let{signer:a,envelope:o}=i;if(a.data.otpVerifiedAt)return{ok:!0,sent:!1,verified:!0};let s=a.data.otp??void 0,c=yo(s,r);if(!c.ok)return c.code===`OTP_WAIT`?Nf(`OTP_WAIT`,`A code was sent a moment ago. Please wait before asking for another.`,{retryAfterSeconds:c.retryAfterSeconds}):U(`RATE_LIMITED`);let l=go();await B(t).signers.updateIf(a.id,{where:{status:`pending`},set:{otp:await bo(l,a.id,r,c),otpTries:0}});try{if(!t.email)throw Error(`no email`);await t.email.send({to:a.data.email,subject:zf(o),text:Bf(l)})}catch{return await B(t).signers.updateIf(a.id,{where:{status:`pending`},set:{otp:s??null,otpTries:a.data.otpTries??5}}),Nf(`OTP_SEND_FAILED`,`We could not email a code. Please try again shortly.`)}return{ok:!0,sent:!0,expiresInSeconds:mo/1e3}}async function Hf(e,t){if(If(e.request))return U(`TOKEN_IN_QUERY`);let n=Ff(e.input),r=_o(Pf(e.input,`code`));if(n===null||r===null)return H([{path:n===null?`token`:`code`,code:`INVALID_INPUT`}]);let i=Date.now();if(await Lf(t,e,`otp-verify`,30,i))return U(`RATE_LIMITED`);let a=N(i),o=await Rf(t,n,a);if(o.error)return o.error;let{signer:s,envelope:c,envelopeId:l}=o;if(s.data.otpVerifiedAt)return{ok:!0,verified:!0};let{signers:u,audit_events:d}=B(t),f=s.data.otp??void 0,p=s.data.otpTries??5,m=await xo(f&&{...f,attempts:p},r,s.id,i),h=()=>Nf(`OTP_LOCKED`,`Too many wrong codes. Ask for a new code.`);if(!m.ok&&m.code!==`OTP_INVALID`)return m.code===`OTP_EXPIRED`?Nf(`OTP_EXPIRED`,`That code has expired. Ask for a new code.`):h();if(!(await u.updateIf(s.id,{where:{status:`pending`,otpTries:{lt:5}},delta:{otpTries:{inc:1}}})).applied)return h();if(!m.ok)return Nf(`OTP_INVALID`,`That code is not right.`,{attemptsLeft:m.attemptsLeft});if(!(await gr(d,l,{type:`otp.verified`,at:a,actor:`signer`,data:{method:`email`,...Ga(c.signerIds.length>1?s.data.order:void 0)},personal:{...e.requestMeta?.ip?{ip:e.requestMeta.ip}:{},...e.requestMeta?.userAgent?{ua:e.requestMeta.userAgent}:{}}},{salt:c.piiSalt})).ok)throw Error(`audit chain contention`);return await u.updateIf(s.id,{where:{status:`pending`,otpVerifiedAt:null},set:{otpVerifiedAt:a,otp:null}}),{ok:!0,verified:!0}}const Uf=/^[!-~]$/;function Wf(e){let t=`/`;for(let n of e){let e=n.charCodeAt(0);t+=Uf.test(n)&&!`()<>[]{}/%#`.includes(n)?n:`#${(e&255).toString(16).padStart(2,`0`)}`}return t}function Gf(e){if(!Number.isFinite(e))return`0`;if(Number.isInteger(e))return String(e);let t=e.toFixed(6).replace(/0+$/,``).replace(/\.$/,``);return t===`-0`?`0`:t}function Q(e){if(e===null)return`null`;if(typeof e==`boolean`)return String(e);if(typeof e==`number`)return Gf(e);if(e instanceof Ao)return Wf(e.name);if(e instanceof Mo)return`${e.num} ${e.gen} R`;if(e instanceof jo){let t=``;for(let n=0;n<e.bytes.length;n++)t+=e.bytes.charCodeAt(n).toString(16).padStart(2,`0`);return`<${t}>`}return Array.isArray(e)?`[${e.map(Q).join(` `)}]`:`<<${[...e].map(([e,t])=>`${Wf(e)} ${Q(t)}`).join(` `)}>>`}const Kf=(e,t=``)=>`<< /Length ${e.length}${t} >>\nstream\n${e}\nendstream`;var qf=class{objects=new Map;next;constructor(e){this.file=e,this.next=e.size}add(e){let t=new Mo(this.next++,0);return this.objects.set(t.num,{gen:0,body:e}),t}replace(e,t){this.objects.set(e.num,{gen:this.file.genOf(e.num),body:t})}bytes(){let{file:e}=this,t=e.bytes.length,n=e.bytes[t-1],r=n===10||n===13?``:`
54
+ `,i=new Map,a=(e,n,a)=>{i.set(e,t+r.length),r+=`${e} ${n} obj\n${a}\nendobj\n`};for(let e of[...this.objects.keys()].sort((e,t)=>e-t)){let t=this.objects.get(e);a(e,t.gen,t.body)}let o=[`Root`,`Info`,`ID`].filter(t=>e.trailer.has(t)).map(t=>` ${Wf(t)} ${Q(e.trailer.get(t))}`).join(``),s=e=>{let t=[];for(let n of e){let e=t.at(-1);e&&e[0]+e[1].length===n?e[1].push(n):t.push([n,[n]])}return t},c=e=>this.objects.get(e)?.gen??0;if(e.xrefKind===`table`){let n=t+r.length;r+=`xref
55
+ `;for(let[e,t]of s([...i.keys()].sort((e,t)=>e-t))){r+=`${e} ${t.length}\n`;for(let e of t)r+=`${String(i.get(e)).padStart(10,`0`)} ${String(c(e)).padStart(5,`0`)} n \n`}r+=`trailer\n<< /Size ${this.next}${o} /Prev ${e.startxref} >>\nstartxref\n${n}\n%%EOF\n`}else{let n=this.next++,a=t+r.length;i.set(n,a);let l=[...i.keys()].sort((e,t)=>e-t),u=``;for(let e of l){let t=i.get(e),n=c(e);u+=String.fromCharCode(1,t>>>24&255,t>>>16&255,t>>>8&255,t&255,n>>8&255,n&255)}let d=s(l).map(([e,t])=>`${e} ${t.length}`).join(` `);r+=`${n} 0 obj\n${Kf(u,` /Type /XRef /Size ${this.next} /W [1 4 2] /Index [${d}]${o} /Prev ${e.startxref}`)}\nendobj\nstartxref\n${a}\n%%EOF\n`}let l=new Uint8Array(t+r.length);l.set(e.bytes);for(let e=0;e<r.length;e++)l[t+e]=r.charCodeAt(e);return l}};function Jf(e){let[t,n,r,i]=e.box;switch(e.rotate){case 90:return[0,1,-1,0,r,n];case 180:return[-1,0,0,-1,r,i];case 270:return[0,-1,1,0,t,i];default:return[1,0,0,1,t,n]}}function Yf(e,t,n){let r=[];for(let i of e){let{x:e,y:a,w:o,h:s}=i.box,c=t-a-s;if(i.kind===`text`){let t=Kt(i.text.replace(/\s+/g,` `).trim());if(!t)continue;let a=i.font===`italic`?`italic`:`regular`,l=Yt(t,1,a),u=Math.max(4,Math.min(14,s*.75,l>0?(o-2)/l:14)),d=c+Math.max(0,(s-u*.72)/2),f=a===`italic`?n.italic:n.regular;r.push(`BT ${Wf(f)} ${P(u)} Tf 0 0 0 rg ${P(e+1)} ${P(d)} Td ${Zt(t)} Tj ET`)}else{let t=[`0.05 0.1 0.45 RG 1.2 w 1 J 1 j`],n=t=>P(e+Math.min(1,Math.max(0,typeof t==`number`?t:0))*o),a=e=>P(c+s-Math.min(1,Math.max(0,typeof e==`number`?e:0))*s);for(let e of i.strokes){let r=e.filter(e=>Array.isArray(e)&&e.length>=2),[i]=r;if(i){t.push(`${n(i[0])} ${a(i[1])} m`);for(let e of r.length===1?r:r.slice(1))t.push(`${n(e[0])} ${a(e[1])} l`);t.push(`S`)}}t.length>1&&r.push(t.join(`
56
56
  `))}}return r.join(`
57
- `)}function Uf(e,t){let n=t;for(let r=2;e.has(n);r++)n=`${t}_${r}`;return n}const Wf=e=>`<< /Type /Font /Subtype /Type1 /BaseFont /${e} /Encoding /WinAnsiEncoding >>`;async function Gf(e,t,n){let r=await Ko.open(e);if(r.encrypted)throw new No(`PDF_ENCRYPTED`,`the PDF is encrypted`);let i=await r.pages(),a=new Bf(r),o={F1:a.add(Wf(`Helvetica`)),F2:a.add(Wf(`Helvetica-Bold`)),F3:a.add(Wf(`Helvetica-Oblique`))},s;for(let[e,n]of[...t].sort((e,t)=>e[0]-t[0])){let t=i[e];if(!t||n.length===0)continue;let c=new Map(t.dict),l=Bo(t.resources)?new Map(t.resources):new Map,u=await r.resolve(l.get(`Font`)),d=Bo(u)?new Map(u):new Map,f=Uf(d,`SemicsF1`);d.set(f,o.F1);let p=Uf(d,`SemicsF3`);d.set(p,o.F3),l.set(`Font`,d),c.set(`Resources`,l);let m=c.get(`Contents`),h=[];if(m instanceof Mo){let e=await r.get(m);h=Array.isArray(e)?e:[m]}else Array.isArray(m)&&(h=m);s??=a.add(zf(`q`));let g=Vf(t).map(P).join(` `),_=Hf(n,qo(t).h,{regular:f,italic:p}),v=a.add(zf(`Q\nq ${g} cm\n${_}\nQ`));c.set(`Contents`,[s,...h,v]),a.replace(t.ref,Rf(c))}let c=await Ko.open(n),l=await r.pagesRef(),u=[];for(let e of await c.pages()){let t=e.dict.get(`Contents`),n=t instanceof Mo?c.streamOf(t):void 0;if(!n)throw Error(`certificate page without content`);let r=a.add(zf(Lo(n.data))),i=`[${e.box.map(P).join(` `)}]`;u.push(a.add(`<< /Type /Page /Parent ${Rf(l)} /MediaBox ${i} /CropBox ${i} /Rotate 0 /Resources << /Font << /F1 ${Rf(o.F1)} /F2 ${Rf(o.F2)} /F3 ${Rf(o.F3)} >> >> /Contents ${Rf(r)} >>`))}let d=await r.get(l);if(!Bo(d))throw new No(`PDF_MALFORMED`,`page tree root is not a dictionary`);let f=new Map(d),p=await r.resolve(f.get(`Kids`)),m=await r.resolve(f.get(`Count`));return f.set(`Kids`,[...Array.isArray(p)?p:[],...u]),f.set(`Count`,(typeof m==`number`?m:i.length)+u.length),a.replace(l,Rf(f)),a.bytes()}function Kf(e={}){let t=[];return new Headers(e.headers).forEach((e,n)=>t.push([n,e])),{__emdashPluginResponse:!0,status:e.status??200,headers:t,body:e.body??null}}const qf=`esign/document`,Jf=/^[A-Za-z0-9_:.-]{1,200}$/,Yf=e=>typeof e==`function`?e:e.handler,Xf=(e,t)=>typeof e==`function`?t:{...e,handler:t},Zf=e=>typeof e==`object`&&!!e&&e.kind===`pdf`&&Array.isArray(e.ids);async function Qf(e,t,n){let r=await ye({secret:await sa(e.kv),purpose:qf,params:{d:t},now:n,ttlMs:36e5});return{url:`/_emdash/api/plugins/${e.plugin.id}/public/download?${r}`,expiresAt:N(Number(r.get(`exp`))*1e3)}}const $f=e=>async(t,n)=>{let r=await e(t,n),i=r?.envelope?.id;return r?.ok!==!0||r.state!==`ready`||!r.document||typeof i!=`string`?r:{...r,document:{...r.document,view:await Qf(n,i,Date.now())}}};function ep(e){let{status:t,body:n}=oe(e);return Kf({status:t,headers:{"content-type":`application/json; charset=utf-8`},body:{kind:`text`,value:JSON.stringify(n)}})}const tp=e=>{try{let t=e.request?.url;return t?new URL(t).searchParams:null}catch{return null}},np=e=>e.replace(/[^A-Za-z0-9._ -]/g,`_`).slice(0,120)||`document.pdf`;async function rp(e,t){if(e.has(`token`))return ep(`TOKEN_IN_QUERY`);let n=await be({secret:await sa(t.kv),purpose:qf,query:e,now:Date.now()});if(!n.ok)return ep(n.error);let r=n.value.d;if(typeof r!=`string`||!Jf.test(r))return ep(`TOKEN_INVALID`);let i=await B(t).envelopes.get(r),a=i?.document;if(!i||!Zf(a)||i.status!==`sent`&&i.status!==`in_progress`)return ep(`ENVELOPE_NOT_FOUND`);let o=await fs(t).pdf_files.getMany(a.ids),s=hs(a.ids.map(e=>o.get(e)));return!s||await F(s)!==i.docSha256?(t.log.error(`uploaded PDF chunks do not match docSha256`,{envelopeId:r}),ep(`INTERNAL`)):Kf({status:200,headers:{"content-type":`application/pdf`,"content-disposition":`inline; filename="${np(a.name)}"`},body:{kind:`bytes`,value:s}})}const ip=e=>{let t=Yf(e);return Xf(e,async(e,n)=>{let r=tp(e);return r?.has(`d`)?rp(r,n):t(e,n)})},ap=e=>t=>Xf(t,$f(e));async function op(e){let{envelope:t,original:n}=e,r=t.document;if(!Zf(r))throw Error(`not an uploaded-PDF envelope`);let i=bn(ds({envelopeId:e.envelopeId,envelope:t,signers:e.signers,events:e.events,head:e.head},{bytes:n.length,pages:r.pages})),a=await Gf(n,us(r.fields,e.signers),i);return{bytes:a,sha256:await F(a)}}async function sp(e,t,n,r){let i=n.document;if(n.status!==`completed`||n.pdfSha256||n.personalPurgedAt||!Zf(i)||n.signerIds.length===0||!n.docSha256)return`skipped`;let{signers:a,audit_events:o,envelopes:s,artifacts:c}=B(e),[l,u,d]=await Promise.all([a.getMany(n.signerIds),o.query({where:{envelopeId:t},orderBy:{seq:`asc`},limit:100}),fs(e).pdf_files.getMany(i.ids)]),f=u.items.map(e=>e.data),p=await br(t,f),m=p.ok&&f.at(-1)?.type===`envelope.completed`&&await Sr(n.docSha256,p.value.head)===n.finalHash,h=n.signerIds.map(e=>l.get(e));if(h.some(e=>e?.status!==`signed`)||!p.ok||!m){let n=r.attempt??0;return n+1>=5?(e.log.error(`signed PDF not generated: the envelope never settled`,{envelopeId:t}),`gave-up`):(await $i(e.cron,t,r.now+6e4,n+1),`retry`)}let g=i.ids.map(e=>d.get(e)),_=hs(g);if(!_||await F(_)!==n.docSha256)return e.log.error(`uploaded PDF chunks do not match docSha256`,{envelopeId:t}),`gave-up`;let{bytes:v,sha256:y}=await op({envelopeId:t,envelope:n,signers:h,events:f,head:p.value.head,original:_}),b=vs(t,v,y,g,_.length);return await c.putMany(b),(await s.updateIf(t,{where:{status:`completed`,pdfSha256:null},set:{pdfSha256:y,pdf:{ids:b.map(e=>e.id),bytes:v.length},updatedAt:N(r.now)}})).applied?(await Na(e.cron,t,r.now),`stored`):`skipped`}async function cp(e,t){if(!e.name.startsWith(Zi))return!1;let n=e.data?.envelopeId;if(typeof n!=`string`||n.length===0)return!1;let r=await B(t).envelopes.get(n);if(!r||!Zf(r.document))return!1;let i=e.data?.attempt;return await sp(t,n,r,{now:Date.now(),attempt:typeof i==`number`&&Number.isSafeInteger(i)?i:0}),!0}async function lp(e,t,n=Date.now()){if(!e.name.startsWith(ja))return!1;let r=e.data?.envelopeId;if(typeof r!=`string`||r.length===0)return!1;let{envelopes:i,signers:a}=B(t),o=await i.get(r);if(!o||o.signerIds.length<2)return!1;let s=L(t);if(o.status!==`completed`||!o.pdfSha256||!s)return!0;let[c,l]=await Promise.all([a.getMany(o.signerIds),t.settings.get(`senderName`)]),u=o.signerIds.flatMap(e=>{let t=c.get(e);return t?.status===`signed`&&!t.copyTokenHash?[{id:e,data:t}]:[]});if(u.length===0)return!0;let d=await Promise.all(u.map(async({id:e,data:t})=>{let n=A();return{id:e,token:n,data:{...t,copyTokenHash:await j(n)}}}));return await a.putMany(d.map(({id:e,data:t})=>({id:e,data:t}))),await I(t).putMany(d.map(e=>({id:Us(e.id),data:Ws($n({to:e.data.email,signerName:e.data.name,title:o.title,sender:tr(t,l),link:`${s}/signed/${e.token}`}),n)}))),!0}const up=(e,t={})=>({...e,actor:`visitor`,data:{...e.data,...t}});async function dp(e,t,n){let{envelopes:r,templates:i,snapshots:a,signers:o,audit_events:s}=B(e),c=await r.get(t);if(!c||c.status!==`draft`||c.selfServe!==!0||!L(e))return`skipped`;let l=z(c.templateId,c.templateVersion),[u,d]=await Promise.all([i.getMany([c.templateId,l]),e.settings.list()]),f=Object.fromEntries(d.map(e=>[e.key,e.value])),p=qr(u.get(c.templateId),u.get(l),c.templateVersion);if(!p.ok)return`skipped`;let m=A(),h=await ii(t,c,p.value,{now:N(n),tokenHash:await j(m),expiryDays:ha(f.expiryDays)});if(!h.ok)return`skipped`;await a.putMany(h.value.chunks);let g=await va(o,h.value.signer,m);await rr(e,{signerId:h.value.signer.id,envelope:h.value.envelope,token:g,senderSetting:f.senderName,now:n});let _=[up(ci(c,`integration`),{source:`self-serve`}),up(li(h.value.envelope,`integration`))];return await s.putMany(await mr(t,_,c.piiSalt)),(await R(r,t,`draft`,`sent`,{...h.value.envelope,...Co(f,p.value)})).ok?`sent`:`skipped`}async function fp(e,t){if(!e.name.startsWith(tc))return!1;let n=e.data?.envelopeId;return typeof n==`string`&&n.length>0&&await dp(t,n,Date.now()),!0}const $=Un($d,{devKey:!1}),pp=jd(rf),mp={handler:uc($)};wa(wo($));var hp={...n(Qd,{routes:{"pro/licence":$.statusRoute(),"pro/envelopes/send":$.gate(`esign/envelope-send`,{handler:Ks}),"pro/templates/self-serve":$.gate(`new`,{handler:dc}),"pro/bulk/start":$.gate(`esign/envelope-send`,{handler:Oo}),"pro/pdf-templates/upload":$.gate(`new`,{handler:Ts}),"pro/pdf-templates/update":$.gate(`new`,{handler:Es}),"pro/pdf-templates/send":$.gate(`esign/envelope-send`,{handler:Ds}),...Cf($)},overrideRoutes:{admin:cl($),"public/otp/send":e=>({...e,handler:Nf}),"public/otp/verify":e=>({...e,handler:Pf}),"public/self-serve/start":e=>({...e,handler:mp.handler}),"public/submit":e=>({...e,handler:pp[`public/submit`]}),"public/session":ap(pp[`public/session`]),"public/download":ip},cron:async(e,t)=>await yf(e,t)||await cp(e,t)||await ul(e,t)||await sf(e,t)||await lp(e,t)||await fp(e,t)||pf(e,t,$)})};export{hp as default,$ as licence};
57
+ `)}function Xf(e,t){let n=t;for(let r=2;e.has(n);r++)n=`${t}_${r}`;return n}const Zf=e=>`<< /Type /Font /Subtype /Type1 /BaseFont /${e} /Encoding /WinAnsiEncoding >>`;async function Qf(e,t,n){let r=await Ko.open(e);if(r.encrypted)throw new No(`PDF_ENCRYPTED`,`the PDF is encrypted`);let i=await r.pages(),a=new qf(r),o={F1:a.add(Zf(`Helvetica`)),F2:a.add(Zf(`Helvetica-Bold`)),F3:a.add(Zf(`Helvetica-Oblique`))},s;for(let[e,n]of[...t].sort((e,t)=>e[0]-t[0])){let t=i[e];if(!t||n.length===0)continue;let c=new Map(t.dict),l=Bo(t.resources)?new Map(t.resources):new Map,u=await r.resolve(l.get(`Font`)),d=Bo(u)?new Map(u):new Map,f=Xf(d,`SemicsF1`);d.set(f,o.F1);let p=Xf(d,`SemicsF3`);d.set(p,o.F3),l.set(`Font`,d),c.set(`Resources`,l);let m=c.get(`Contents`),h=[];if(m instanceof Mo){let e=await r.get(m);h=Array.isArray(e)?e:[m]}else Array.isArray(m)&&(h=m);s??=a.add(Kf(`q`));let g=Jf(t).map(P).join(` `),_=Yf(n,qo(t).h,{regular:f,italic:p}),v=a.add(Kf(`Q\nq ${g} cm\n${_}\nQ`));c.set(`Contents`,[s,...h,v]),a.replace(t.ref,Q(c))}let c=await Ko.open(n),l=await r.pagesRef(),u=[];for(let e of await c.pages()){let t=e.dict.get(`Contents`),n=t instanceof Mo?c.streamOf(t):void 0;if(!n)throw Error(`certificate page without content`);let r=a.add(Kf(Lo(n.data))),i=`[${e.box.map(P).join(` `)}]`;u.push(a.add(`<< /Type /Page /Parent ${Q(l)} /MediaBox ${i} /CropBox ${i} /Rotate 0 /Resources << /Font << /F1 ${Q(o.F1)} /F2 ${Q(o.F2)} /F3 ${Q(o.F3)} >> >> /Contents ${Q(r)} >>`))}let d=await r.get(l);if(!Bo(d))throw new No(`PDF_MALFORMED`,`page tree root is not a dictionary`);let f=new Map(d),p=await r.resolve(f.get(`Kids`)),m=await r.resolve(f.get(`Count`));return f.set(`Kids`,[...Array.isArray(p)?p:[],...u]),f.set(`Count`,(typeof m==`number`?m:i.length)+u.length),a.replace(l,Q(f)),a.bytes()}function $f(e={}){let t=[];return new Headers(e.headers).forEach((e,n)=>t.push([n,e])),{__emdashPluginResponse:!0,status:e.status??200,headers:t,body:e.body??null}}const ep=`esign/document`,tp=/^[A-Za-z0-9_:.-]{1,200}$/,np=e=>typeof e==`function`?e:e.handler,rp=(e,t)=>typeof e==`function`?t:{...e,handler:t},ip=e=>typeof e==`object`&&!!e&&e.kind===`pdf`&&Array.isArray(e.ids);async function ap(e,t,n){let r=await ye({secret:await sa(e.kv),purpose:ep,params:{d:t},now:n,ttlMs:36e5});return{url:`/_emdash/api/plugins/${e.plugin.id}/public/download?${r}`,expiresAt:N(Number(r.get(`exp`))*1e3)}}const op=e=>async(t,n)=>{let r=await e(t,n),i=r?.envelope?.id;return r?.ok!==!0||r.state!==`ready`||!r.document||typeof i!=`string`?r:{...r,document:{...r.document,view:await ap(n,i,Date.now())}}};function sp(e){let{status:t,body:n}=oe(e);return $f({status:t,headers:{"content-type":`application/json; charset=utf-8`},body:{kind:`text`,value:JSON.stringify(n)}})}const cp=e=>{try{let t=e.request?.url;return t?new URL(t).searchParams:null}catch{return null}},lp=e=>e.replace(/[^A-Za-z0-9._ -]/g,`_`).slice(0,120)||`document.pdf`;async function up(e,t){if(e.has(`token`))return sp(`TOKEN_IN_QUERY`);let n=await be({secret:await sa(t.kv),purpose:ep,query:e,now:Date.now()});if(!n.ok)return sp(n.error);let r=n.value.d;if(typeof r!=`string`||!tp.test(r))return sp(`TOKEN_INVALID`);let i=await B(t).envelopes.get(r),a=i?.document;if(!i||!ip(a)||i.status!==`sent`&&i.status!==`in_progress`)return sp(`ENVELOPE_NOT_FOUND`);let o=await fs(t).pdf_files.getMany(a.ids),s=hs(a.ids.map(e=>o.get(e)));return!s||await F(s)!==i.docSha256?(t.log.error(`uploaded PDF chunks do not match docSha256`,{envelopeId:r}),sp(`INTERNAL`)):$f({status:200,headers:{"content-type":`application/pdf`,"content-disposition":`inline; filename="${lp(a.name)}"`},body:{kind:`bytes`,value:s}})}const dp=e=>{let t=np(e);return rp(e,async(e,n)=>{let r=cp(e);return r?.has(`d`)?up(r,n):t(e,n)})},fp=e=>t=>rp(t,op(e));async function pp(e){let{envelope:t,original:n}=e,r=t.document;if(!ip(r))throw Error(`not an uploaded-PDF envelope`);let i=bn(ds({envelopeId:e.envelopeId,envelope:t,signers:e.signers,events:e.events,head:e.head},{bytes:n.length,pages:r.pages})),a=await Qf(n,us(r.fields,e.signers),i);return{bytes:a,sha256:await F(a)}}async function mp(e,t,n,r){let i=n.document;if(n.status!==`completed`||n.pdfSha256||n.personalPurgedAt||!ip(i)||n.signerIds.length===0||!n.docSha256)return`skipped`;let{signers:a,audit_events:o,envelopes:s,artifacts:c}=B(e),[l,u,d]=await Promise.all([a.getMany(n.signerIds),o.query({where:{envelopeId:t},orderBy:{seq:`asc`},limit:100}),fs(e).pdf_files.getMany(i.ids)]),f=u.items.map(e=>e.data),p=await br(t,f),m=p.ok&&f.at(-1)?.type===`envelope.completed`&&await Sr(n.docSha256,p.value.head)===n.finalHash,h=n.signerIds.map(e=>l.get(e));if(h.some(e=>e?.status!==`signed`)||!p.ok||!m){let n=r.attempt??0;return n+1>=5?(e.log.error(`signed PDF not generated: the envelope never settled`,{envelopeId:t}),`gave-up`):(await $i(e.cron,t,r.now+6e4,n+1),`retry`)}let g=i.ids.map(e=>d.get(e)),_=hs(g);if(!_||await F(_)!==n.docSha256)return e.log.error(`uploaded PDF chunks do not match docSha256`,{envelopeId:t}),`gave-up`;let{bytes:v,sha256:y}=await pp({envelopeId:t,envelope:n,signers:h,events:f,head:p.value.head,original:_}),b=vs(t,v,y,g,_.length);return await c.putMany(b),(await s.updateIf(t,{where:{status:`completed`,pdfSha256:null},set:{pdfSha256:y,pdf:{ids:b.map(e=>e.id),bytes:v.length},updatedAt:N(r.now)}})).applied?(await Na(e.cron,t,r.now),`stored`):`skipped`}async function hp(e,t){if(!e.name.startsWith(Zi))return!1;let n=e.data?.envelopeId;if(typeof n!=`string`||n.length===0)return!1;let r=await B(t).envelopes.get(n);if(!r||!ip(r.document))return!1;let i=e.data?.attempt;return await mp(t,n,r,{now:Date.now(),attempt:typeof i==`number`&&Number.isSafeInteger(i)?i:0}),!0}async function gp(e,t,n=Date.now()){if(!e.name.startsWith(ja))return!1;let r=e.data?.envelopeId;if(typeof r!=`string`||r.length===0)return!1;let{envelopes:i,signers:a}=B(t),o=await i.get(r);if(!o||o.signerIds.length<2)return!1;let s=L(t);if(o.status!==`completed`||!o.pdfSha256||!s)return!0;let[c,l]=await Promise.all([a.getMany(o.signerIds),t.settings.get(`senderName`)]),u=o.signerIds.flatMap(e=>{let t=c.get(e);return t?.status===`signed`&&!t.copyTokenHash?[{id:e,data:t}]:[]});if(u.length===0)return!0;let d=await Promise.all(u.map(async({id:e,data:t})=>{let n=A();return{id:e,token:n,data:{...t,copyTokenHash:await j(n)}}}));return await a.putMany(d.map(({id:e,data:t})=>({id:e,data:t}))),await I(t).putMany(d.map(e=>({id:Us(e.id),data:Ws($n({to:e.data.email,signerName:e.data.name,title:o.title,sender:tr(t,l),link:`${s}/signed/${e.token}`}),n)}))),!0}const _p=(e,t={})=>({...e,actor:`visitor`,data:{...e.data,...t}});async function vp(e,t,n){let{envelopes:r,templates:i,snapshots:a,signers:o,audit_events:s}=B(e),c=await r.get(t);if(!c||c.status!==`draft`||c.selfServe!==!0||!L(e))return`skipped`;let l=R(c.templateId,c.templateVersion),[u,d]=await Promise.all([i.getMany([c.templateId,l]),e.settings.list()]),f=Object.fromEntries(d.map(e=>[e.key,e.value])),p=Jr(u.get(c.templateId),u.get(l),c.templateVersion);if(!p.ok)return`skipped`;let m=A(),h=await ai(t,c,p.value,{now:N(n),tokenHash:await j(m),expiryDays:ha(f.expiryDays)});if(!h.ok)return`skipped`;await a.putMany(h.value.chunks);let g=await va(o,h.value.signer,m);await rr(e,{signerId:h.value.signer.id,envelope:h.value.envelope,token:g,senderSetting:f.senderName,now:n});let _=[_p(li(c,`integration`),{source:`self-serve`}),_p(ui(h.value.envelope,`integration`))];return await s.putMany(await mr(t,_,c.piiSalt)),(await kr(r,t,`draft`,`sent`,{...h.value.envelope,...Co(f,p.value)})).ok?`sent`:`skipped`}async function yp(e,t){if(!e.name.startsWith(tc))return!1;let n=e.data?.envelopeId;return typeof n==`string`&&n.length>0&&await vp(t,n,Date.now()),!0}const $=Un(cf,{devKey:!1}),bp=Md(ff),xp={handler:uc($)};wa(wo($));var Sp={...n(sf,{routes:{"pro/licence":$.statusRoute(),"pro/envelopes/send":$.gate(`esign/envelope-send`,{handler:Ks}),"pro/templates/self-serve":$.gate(`new`,{handler:dc}),"pro/bulk/start":$.gate(`esign/envelope-send`,{handler:Oo}),"pro/pdf-templates/upload":$.gate(`new`,{handler:Ts}),"pro/pdf-templates/update":$.gate(`new`,{handler:Es}),"pro/pdf-templates/send":$.gate(`esign/envelope-send`,{handler:Ds}),...jf($)},overrideRoutes:{admin:cl($),"public/otp/send":e=>({...e,handler:Vf}),"public/otp/verify":e=>({...e,handler:Hf}),"public/self-serve/start":e=>({...e,handler:xp.handler}),"public/submit":e=>({...e,handler:bp[`public/submit`]}),"public/session":fp(bp[`public/session`]),"public/download":dp},cron:async(e,t)=>await Df(e,t)||await hp(e,t)||await ul(e,t)||await hf(e,t)||await gp(e,t)||await yp(e,t)||xf(e,t,$)})};export{Sp as default,$ as licence};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@semics-tech/emdash-esign-pro",
3
- "version": "1.0.0-rc.1",
3
+ "version": "1.0.0-rc.2",
4
4
  "type": "module",
5
5
  "description": "E-sign Pro: the semics-esign core plus Pro features, same slug (proprietary)",
6
6
  "license": "SEE LICENSE IN LICENSE",