@north-light/crouter 0.3.194 → 0.3.195
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/pages/bundle.js +9 -9
- package/dist/pages/comments.d.ts +9 -0
- package/dist/pages/comments.js +53 -0
- package/dist/pages/elements/cards.js +19 -2
- package/dist/pages/elements/options.js +27 -2
- package/dist/pages/elements/table.js +31 -2
- package/dist/pages/elements/text.js +19 -2
- package/dist/pages/host.d.ts +26 -0
- package/dist/pages/host.js +33 -0
- package/package.json +1 -1
- package/runtime.lock.json +2 -2
package/dist/pages/bundle.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";(()=>{function
|
|
1
|
+
"use strict";(()=>{function K(o){switch(o.kind){case"whole":return"whole";case"option":return`option:${o.optionId}`;case"row":return`row:${o.rowId}`;case"column":return`column:${o.columnId}`;case"card":return`card:${o.cardId}`;case"range":return`range:${o.start}:${o.end}`}}function b(o,t){let e=K(t);return o.find(r=>K(r.anchor)===e)}function R(o,t,e){let r=K(t),n=o.filter(s=>K(s.anchor)!==r),i=e.trim();if(i==="")return n;let a=o.find(s=>K(s.anchor)===r);return[...n,{id:a?.id??Gt(),anchor:t,text:i}]}var Z=0;function Kt(o){if(typeof o!="object"||o===null)return!1;let t=o;switch(t.kind){case"whole":return!0;case"option":return typeof t.optionId=="string";case"row":return typeof t.rowId=="string";case"column":return typeof t.columnId=="string";case"card":return typeof t.cardId=="string";case"range":return typeof t.start=="number"&&typeof t.end=="number"&&typeof t.quote=="string";default:return!1}}function H(o){if(!Array.isArray(o))return[];let t=[];for(let e of o){if(typeof e!="object"||e===null)continue;let{id:r,anchor:n,text:i}=e;if(typeof r!="string"||r===""||typeof i!="string"||i.trim()===""||!Kt(n)||b(t,n)!==void 0)continue;t.push({id:r,anchor:{...n},text:i});let a=/^c(\d+)$/.exec(r);a!==null&&(Z=Math.max(Z,Number(a[1])))}return t}function Gt(){return Z+=1,`c${Z}`}function nt(o){switch(o.kind){case"whole":return"this";case"range":return`\u201C${o.quote}\u201D`;default:return K(o)}}function Q(){return typeof window>"u"?void 0:window.crtr}function vt(o){if(o instanceof Error&&o.message!=="")return o.message;let t=String(o);return t===""?"unknown error":t}function xt(o){return{status:"unavailable",reason:`host bridge does not provide ${o}()`}}function $(o,t){let e=Q();if(typeof e?.respond!="function")return xt("respond");try{return e.respond(o,t),{status:"ok"}}catch(r){return{status:"failed",reason:vt(r)}}}function I(o){let t=Q();if(typeof t?.savedResponse=="function")try{let e=t.savedResponse(o);return typeof e=="object"&&e!==null&&!Array.isArray(e)?e:void 0}catch{return}}function B(o){return Array.isArray(o)?o.filter(t=>typeof t=="string"):[]}async function G(o){let t=Q();if(typeof t?.artifact?.data!="function")return xt("artifact.data");try{return{status:"ok",data:await t.artifact.data(o)}}catch(e){return{status:"failed",reason:vt(e)}}}async function yt(o,t,e){let r=Q();if(typeof r?.mountWorkspaceComponent!="function")return"unavailable";try{return await r.mountWorkspaceComponent(o,t,e)}catch{return"unavailable"}}function v(o,t){customElements.define(o,t)}function k(o){let t=o.querySelector('script[type="application/json"]');if(t===null)return{status:"invalid",reason:"slot has no application/json config"};let e=t.textContent??"";if(e.trim()==="")return{status:"invalid",reason:"slot config is empty"};let r;try{r=JSON.parse(e)}catch(n){return{status:"invalid",reason:`slot config is not valid JSON: ${n instanceof Error&&n.message!==""?n.message:"invalid JSON"}`}}return typeof r!="object"||r===null||Array.isArray(r)?{status:"invalid",reason:"slot config must be a JSON object"}:{status:"ok",config:r}}function N(o){let t=o.getAttribute("slot-id")?.trim();return t===void 0||t===""?void 0:t}var Ft='<svg viewBox="0 0 16 16" aria-hidden="true" focusable="false"><path d="M2.5 3.5h11v7h-6l-3 2.5v-2.5h-2z"/><path d="M8 5.5v3M6.5 7h3"/></svg>',Wt='<svg viewBox="0 0 16 16" aria-hidden="true" focusable="false"><path d="M2.5 3.5h11v7h-6l-3 2.5v-2.5h-2z"/><path d="M5 6.25h6M5 8.25h4"/></svg>',Et=`
|
|
2
2
|
:host {
|
|
3
3
|
display: block;
|
|
4
4
|
}
|
|
@@ -241,7 +241,7 @@
|
|
|
241
241
|
color: var(--crtr-color-text);
|
|
242
242
|
font-family: var(--crtr-font-mono);
|
|
243
243
|
}
|
|
244
|
-
`,
|
|
244
|
+
`,wt=0;function qt(o){return o instanceof HTMLTextAreaElement||o instanceof HTMLElement&&o.isContentEditable?!0:o instanceof HTMLInputElement?o.type!=="checkbox"&&o.type!=="radio":!1}var it=class extends HTMLElement{#n;#d;#s;#t=new Map;#r=[];#e=[];#o=[];#l;#c;#a;#u=!1;constructor(){super(),this.#n=this.attachShadow({mode:"open"})}connectedCallback(){if(this.#u)return;this.#u=!0,this.#s=N(this);let t=k(this);if(t.status!=="ok"){this.#h(t.reason);return}let e=t.config;if(!Array.isArray(e.options)||e.options.length===0){this.#h("options config lists no options");return}this.#d=e,this.#r=e.options.map(r=>r.id),this.#i(e),this.#x(e),this.#E()}disconnectedCallback(){document.removeEventListener("pointerdown",this.#m,!0)}#i(t){if(this.#s===void 0)return;let e=I(this.#s);if(e===void 0)return;let r=B(e.selectedOptionIds);this.#e=this.#r.filter(n=>r.includes(n)),t.mode==="single"&&(this.#e=this.#e.slice(0,1)),this.#o=H(e.comments).filter(n=>n.anchor.kind!=="option"||this.#r.includes(n.anchor.optionId)),t.allowFreetext===!0&&typeof e.freetext=="string"&&e.freetext!==""&&(this.#l=e.freetext)}#h(t){let e=document.createElement("style");e.textContent=Et;let r=document.createElement("div");r.part.add("unavailable"),r.setAttribute("role","status");let n=document.createElement("span");n.part.add("reason"),n.textContent=t,r.append("Options unavailable: ",n),this.#n.replaceChildren(e,r)}#x(t){let e=document.createElement("style");e.textContent=Et;let r=document.createElement("div");r.part.add("container");let n=document.createElement("div");n.part.add("list"),t.mode==="single"&&n.setAttribute("role","radiogroup"),wt+=1;let i=`crtr-options-${wt}`;for(let a of t.options)n.append(this.#p(t,a,i));r.append(n),t.allowFreetext===!0&&r.append(this.#g(t)),r.addEventListener("keydown",a=>this.#w(a)),this.#n.replaceChildren(e,r)}#p(t,e,r){let n=document.createElement("div");n.part.add("option"),n.dataset.optionId=e.id;let i=document.createElement("label");i.part.add("option-label");let a=document.createElement("input");a.part.add("option-control"),a.type=t.mode==="single"?"radio":"checkbox",a.name=r,a.value=e.id,a.addEventListener("change",()=>this.#k(e.id,a.checked)),a.addEventListener("focus",()=>this.#y(e.id));let s=document.createElement("span");s.part.add("option-text");let c=document.createElement("span");if(c.part.add("option-title"),c.textContent=e.label,s.append(c),e.description!==void 0&&e.description!==""){let y=document.createElement("span");y.part.add("option-description"),y.textContent=e.description,s.append(y)}i.append(a,s);let d=document.createElement("button");d.part.add("comment"),d.type="button",d.setAttribute("aria-haspopup","dialog"),d.addEventListener("click",()=>{this.#a===e.id?this.#f():this.#A(e.id)});let u=document.createElement("div");u.part.add("comment-popover"),u.setAttribute("role","dialog"),u.hidden=!0;let g=document.createElement("p");g.part.add("comment-subject"),g.textContent=`Comment on ${e.label}`,u.setAttribute("aria-label",g.textContent);let m=document.createElement("textarea");m.part.add("comment-input"),m.placeholder="What should the agent know about this?",m.addEventListener("keydown",y=>{if(y.key==="Enter"&&(y.metaKey||y.ctrlKey)){y.preventDefault(),this.#T(e.id);return}y.key==="Escape"&&(y.preventDefault(),this.#f())});let V=document.createElement("div");V.part.add("comment-actions");let P=document.createElement("span");P.part.add("comment-hint");let A=document.createElement("span"),T=document.createElement("button");T.part.add("comment-cancel"),T.type="button",T.textContent="Cancel",T.addEventListener("click",()=>this.#f());let M=document.createElement("button");return M.part.add("comment-save"),M.type="button",M.textContent="Save",M.addEventListener("click",()=>this.#T(e.id)),A.append(T,M),V.append(P,A),u.append(g,m,V),n.append(i,d,u),n.addEventListener("mouseenter",()=>this.#y(e.id)),n.addEventListener("mouseleave",()=>this.#v(e.id)),this.#t.set(e.id,{id:e.id,label:e.label,root:n,control:a,comment:d,popover:u,input:m,hint:P}),n}#g(t){let e=document.createElement("label");e.part.add("freetext");let r=document.createElement("span");r.part.add("freetext-label"),r.textContent=t.freetextLabel??"Something else";let n=document.createElement("textarea");return n.part.add("freetext-input"),n.placeholder=t.freetextPlaceholder??"Answer in your own words\u2026",this.#l!==void 0&&(n.value=this.#l),n.addEventListener("input",()=>{this.#l=n.value===""?void 0:n.value,this.#b()}),e.append(r,n),e}#w(t){if(t.metaKey||t.ctrlKey||t.altKey||qt(t.target))return;let e=t.key.toLowerCase(),r=this.#c??this.#e.at(-1)??this.#r[0];if(r!==void 0){if(e==="j"||e==="k"){t.preventDefault();let n=Math.max(0,this.#r.indexOf(r)),i=e==="j"?1:-1,a=this.#r[(n+i+this.#r.length)%this.#r.length];this.#y(a),this.#t.get(a)?.control.focus();return}if(e==="x"){t.preventDefault();let n=this.#e.includes(r);this.#k(r,this.#d?.mode==="single"?!0:!n);return}e==="c"&&(t.preventDefault(),this.#A(r))}}#y(t){this.#c!==t&&(this.#c=t,this.#E())}#v(t){this.#c===t&&(this.#c=void 0,this.#E())}#k(t,e){if(this.#d!==void 0){if(this.#d.mode==="single")this.#e=[t];else{let r=e?[...this.#e,t]:this.#e.filter(n=>n!==t);this.#e=this.#r.filter(n=>r.includes(n))}this.#y(t),this.#E(),this.#b()}}#m=t=>{if(this.#a===void 0)return;let e=this.#t.get(this.#a);if(e===void 0)return;let r=t.composedPath();r.includes(e.popover)||r.includes(e.comment)||this.#f(!1)};#A(t){let e=this.#t.get(t);e!==void 0&&(this.#a===void 0&&document.addEventListener("pointerdown",this.#m,!0),this.#a=t,this.#c=t,e.input.value=b(this.#o,ot(t))?.text??"",this.#E(),e.input.focus())}#f(t=!0){if(this.#a===void 0)return;let e=this.#t.get(this.#a);this.#a=void 0,document.removeEventListener("pointerdown",this.#m,!0),this.#E(),t&&e?.comment.focus()}#T(t){let e=this.#t.get(t);e!==void 0&&(this.#o=R(this.#o,ot(t),e.input.value),this.#f(),this.#b())}#E(){for(let t of this.#t.values()){let e=this.#e.includes(t.id);t.control.checked=e,t.root.dataset.selected=String(e),t.root.dataset.active=String(this.#c===t.id);let r=b(this.#o,ot(t.id));t.comment.dataset.state=r===void 0?"empty":"commented",t.comment.innerHTML=r===void 0?Ft:Wt,t.comment.setAttribute("aria-label",r===void 0?`Comment on ${t.label}`:`Edit comment on ${t.label}`);let n=this.#a===t.id;t.comment.setAttribute("aria-expanded",String(n)),t.popover.hidden=!n,t.hint.textContent=r===void 0?"\u2318\u21B5 to save":"empty to delete"}}#b(){if(this.#s===void 0)return;let t={selectedOptionIds:[...this.#e],comments:this.#o.map(e=>({...e}))};this.#d?.allowFreetext===!0&&this.#l!==void 0&&(t.freetext=this.#l),$(this.#s,t)}};function ot(o){return{kind:"option",optionId:o}}v("crtr-options",it);var at={kind:"whole"},F="the whole passage",Y="the selected text",Vt=6,St="comment-popover",Ut=`
|
|
245
245
|
:host {
|
|
246
246
|
display: block;
|
|
247
247
|
}
|
|
@@ -537,7 +537,7 @@
|
|
|
537
537
|
color: var(--crtr-color-text);
|
|
538
538
|
font-family: var(--crtr-font-mono);
|
|
539
539
|
}
|
|
540
|
-
`,yt="http://www.w3.org/2000/svg",At="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z",Et=[At,"M12 7v6","M9 10h6"],wt=[At,"M13 8H7","M17 12H7"],Ft=["M12 20h9","M16.376 3.622a1 1 0 0 1 3.002 3.002L7.368 18.635a2 2 0 0 1-.855.506l-2.872.838a.5.5 0 0 1-.62-.62l.838-2.872a2 2 0 0 1 .506-.854z","m15 5 3 3"],qt=["M20 6 9 17l-5-5"];function Y(o){let t=document.createElementNS(yt,"svg");t.setAttribute("viewBox","0 0 24 24"),t.setAttribute("fill","none"),t.setAttribute("stroke","currentColor"),t.setAttribute("stroke-width","2"),t.setAttribute("stroke-linecap","round"),t.setAttribute("stroke-linejoin","round"),t.setAttribute("aria-hidden","true");for(let e of o){let r=document.createElementNS(yt,"path");r.setAttribute("d",e),t.append(r)}return t}function Vt(o){let t=[],e=/\n{2,}/g,r=0,n;for(;(n=e.exec(o))!==null;)t.push({start:r,text:o.slice(r,n.index)}),r=n.index+n[0].length;return t.push({start:r,text:o.slice(r)}),t.filter(i=>i.text.trim().length>0)}function Ut(o,t){let e=t.filter(i=>i.anchor.kind==="range").filter(i=>i.anchor.end>o.start&&i.anchor.start<o.start+o.text.length).sort((i,a)=>i.anchor.start-a.anchor.start),r=[],n=0;for(let i of e){let a=Math.max(n,i.anchor.start-o.start),s=Math.min(o.text.length,i.anchor.end-o.start);s<=a||(a>n&&r.push({text:o.text.slice(n,a)}),r.push({text:o.text.slice(a,s),comment:i}),n=s)}return n<o.text.length&&r.push({text:o.text.slice(n)}),r}function Yt(o){return(o.nodeType===Node.ELEMENT_NODE?o:o.parentElement)?.closest("[data-paragraph]")??null}function Xt(o,t,e){let r=document.createRange();r.selectNodeContents(o),r.setEnd(t,e);let n=r.cloneContents();for(let i of n.querySelectorAll('[part="comment-bubble"]'))i.remove();return n.textContent?.length??0}function Ct(o){let t=o.cloneNode(!0);for(let e of t.querySelectorAll('[part="comment-bubble"]'))e.remove();return t.textContent?.length??0}function kt(o,t,e,r){let n=Array.from(o.querySelectorAll("[data-paragraph]")),i=Yt(t);if(i){if(r==="end"&&e===0){let c=n.indexOf(i),d=n[c-1];if(d)return{paragraph:d,offset:Ct(d)}}return{paragraph:i,offset:Xt(i,t,e)}}let a=document.createRange();a.setStart(t,e),a.collapse(!0);let s=r==="start"?n:[...n].reverse();for(let c of s){let d=document.createRange();d.selectNodeContents(c);let u=a.compareBoundaryPoints(r==="start"?Range.START_TO_START:Range.START_TO_END,d);if(r==="start"&&u<=0||r==="end"&&u>=0)return{paragraph:c,offset:r==="start"?0:Ct(c)}}return null}function Jt(o,t){let e=o,r=[typeof e.getSelection=="function"?e.getSelection():null,document.getSelection()];for(let n of r){if(!n||n.isCollapsed||n.rangeCount===0)continue;let i=n.getRangeAt(0);if(t.contains(i.startContainer)&&t.contains(i.endContainer))return i}return null}function X(o){o.setAttribute("aria-haspopup","dialog"),o.setAttribute("aria-controls",Tt),o.setAttribute("aria-expanded","false")}var nt=class extends HTMLElement{#n;#d=document.createElement("div");#c=document.createElement("div");#t=document.createElement("span");#r=document.createElement("button");#e=document.createElement("button");#i=document.createElement("span");#l=document.createElement("div");#s=document.createElement("textarea");#a=document.createElement("div");#u=document.createElement("div");#o=document.createElement("button");#p=document.createElement("div");#f=document.createElement("span");#m=document.createElement("div");#h=document.createElement("div");#v=document.createElement("p");#x=document.createElement("blockquote");#E=document.createElement("textarea");#g=document.createElement("span");#w=document.createElement("button");#y=document.createElement("button");#C={initialText:""};#A;#b="";#k=[];#T=!1;#H=!1;#N=null;#M=null;constructor(){super(),this.#n=this.attachShadow({mode:"open"});let t=document.createElement("style");t.textContent=Wt,this.#d.part.add("container"),this.#c.part.add("toolbar"),this.#t.part.add("edited"),this.#t.textContent="edited",this.#t.hidden=!0,this.#r.type="button",this.#r.part.add("comment-trigger"),this.#r.part.add("whole-comment"),X(this.#r),this.#r.addEventListener("click",()=>{this.#S(rt,_,this.#r,"end")}),this.#e.type="button",this.#e.part.add("edit-toggle"),this.#e.hidden=!0,this.#e.append(this.#i),this.#e.addEventListener("click",()=>{this.#T=!this.#T,this.#I(),this.#_(),this.#L(),this.#T?this.#s.focus():this.#a.focus()}),this.#c.append(this.#t,this.#r,this.#e),this.#l.part.add("surface"),this.#s.part.add("editor"),this.#s.addEventListener("input",()=>{this.#b=this.#s.value,this.#L(),this.#P()}),this.#a.part.add("body"),this.#a.tabIndex=0,this.#u.part.add("prose"),this.#o.type="button",this.#o.part.add("comment-trigger"),this.#o.part.add("selection-comment"),this.#o.hidden=!0,X(this.#o),this.#o.append(Y(Et),document.createTextNode("Comment")),this.#o.addEventListener("mousedown",n=>n.preventDefault()),this.#o.addEventListener("click",()=>{let n=this.#N;n!==null&&this.#S(n.anchor,q,this.#o,"start",n.anchor.quote)}),this.#a.append(this.#u,this.#o),this.#a.addEventListener("mouseup",()=>this.#q()),this.#p.part.add("comment-rail"),this.#p.hidden=!0,this.#f.part.add("comment-count"),this.#m.part.add("comment-chips"),this.#p.append(this.#f,this.#m),this.#h.part.add("popover"),this.#h.hidden=!0,this.#h.id=Tt,this.#h.setAttribute("role","dialog"),this.#v.part.add("popover-subject"),this.#x.part.add("popover-quote"),this.#x.hidden=!0,this.#E.part.add("popover-input"),this.#E.placeholder="What should the agent know about this?",this.#E.addEventListener("keydown",n=>{n.key==="Enter"&&(n.metaKey||n.ctrlKey)&&(n.preventDefault(),this.#W())}),this.#g.part.add("popover-hint"),this.#y.type="button",this.#y.part.add("popover-cancel"),this.#y.textContent="Cancel",this.#y.addEventListener("click",()=>this.#R()),this.#w.type="button",this.#w.part.add("popover-save"),this.#w.textContent="Save",this.#w.addEventListener("click",()=>this.#W());let e=document.createElement("div");e.part.add("popover-actions");let r=document.createElement("div");r.part.add("popover-buttons"),r.append(this.#y,this.#w),e.append(this.#g,r),this.#h.append(this.#v,this.#x,this.#E,e),this.#d.append(this.#c,this.#l,this.#p,this.#h),this.#n.append(t,this.#d),this.addEventListener("keydown",this.#U)}connectedCallback(){if(this.#H)return;let t=C(this);if(t.status!=="ok"){this.#z(t.reason);return}if(typeof t.config.initialText!="string"){this.#z("text config has no initialText string");return}this.#H=!0,this.#C=t.config,this.#A=$(this),this.#b=t.config.initialText,this.#T=t.config.editable===!0&&this.#b.length===0,this.#L(),this.#_(),this.#K()}disconnectedCallback(){document.removeEventListener("pointerdown",this.#O,!0)}#B(){return{text:this.#b,edited:this.#b!==this.#C.initialText,comments:this.#k}}#P(){this.#A!==void 0&&R(this.#A,this.#B())}#z(t){let e=document.createElement("div");e.part.add("unavailable"),e.setAttribute("role","status");let r=document.createElement("span");r.part.add("reason"),r.textContent=t,e.append("Text unavailable: ",r),this.#d.replaceChildren(e)}#L(){this.#t.hidden=this.#b===this.#C.initialText;let t=x(this.#k,rt);this.#r.replaceChildren(Y(t?wt:Et)),this.#r.dataset.state=t?"on":"off",this.#r.setAttribute("aria-label",`${t?"Edit comment on":"Comment on"} ${_}`),this.#e.hidden=this.#C.editable!==!0,this.#e.dataset.state=this.#T?"on":"off",this.#i.textContent=this.#T?"Done":"Edit",this.#e.replaceChildren(Y(this.#T?qt:Ft),this.#i)}#_(){if(this.#T){this.#s.value!==this.#b&&(this.#s.value=this.#b),this.#s.placeholder=this.#C.placeholder??"Write your answer\u2026",this.#l.firstChild!==this.#s&&this.#l.replaceChildren(this.#s);return}this.#l.firstChild!==this.#a&&this.#l.replaceChildren(this.#a),this.#j()}#j(){let t=Vt(this.#b);if(t.length===0){let r=document.createElement("p");r.part.add("placeholder"),r.textContent=this.#C.placeholder??"Nothing yet.",this.#u.replaceChildren(r);return}let e=t.map(r=>{let n=document.createElement("p");n.dataset.paragraph="",n.dataset.start=String(r.start);for(let i of Ut(r,this.#k))n.append(i.comment?this.#F(i.text,i.comment):i.text);return n});this.#u.replaceChildren(...e)}#F(t,e){let r=document.createElement("span");r.part.add("commented"),r.tabIndex=0,r.dataset.commentId=e.id,X(r);let n=document.createElement("span");n.part.add("comment-bubble"),n.setAttribute("role","note");let i=document.createElement("span");i.part.add("bubble-label"),i.textContent="Comment";let a=document.createElement("span");return a.textContent=e.text,n.append(i,a),r.append(t,n),r}#K(){let t=this.#k.length;if(this.#p.hidden=t===0,t===0){this.#m.replaceChildren();return}this.#f.textContent=`${t} comment${t===1?"":"s"}`;let e=this.#k.map(r=>{let n=document.createElement("button");n.type="button",n.part.add("comment-trigger"),n.part.add("comment-chip"),n.dataset.commentId=r.id,X(n);let i=document.createElement("span");i.textContent=r.text,n.append(Y(wt),i);let a=r.anchor.kind==="range"?r.anchor:void 0;return n.setAttribute("aria-label",`Edit comment on ${a?q:_}`),n.addEventListener("click",()=>{this.#S(r.anchor,a?q:_,n,"start",a?.quote)}),n});this.#m.replaceChildren(...e)}#D(){let t=Jt(this.#n,this.#a);if(t===null)return null;let e=kt(this.#a,t.startContainer,t.startOffset,"start"),r=kt(this.#a,t.endContainer,t.endOffset,"end");if(e===null||r===null||e.paragraph!==r.paragraph)return null;let n=Number(e.paragraph.dataset.start??"0"),i=n+e.offset,a=n+r.offset;if(a<=i)return null;let s=t.getBoundingClientRect(),c=this.#a.getBoundingClientRect();return{anchor:{kind:"range",start:i,end:a,quote:this.#b.slice(i,a)},left:s.left-c.left,top:s.bottom-c.top+4}}#q(){if(this.#T||this.#M!==null)return;let t=this.#D();if(t===null){this.#I();return}this.#N=t,this.#o.hidden=!1,this.#o.style.left=`${t.left}px`,this.#o.style.top=`${t.top}px`}#I(){this.#N=null,this.#o.hidden=!0}#S(t,e,r,n,i){let a=this.#M;if(a!==null){if(a.trigger===r){this.#R();return}a.trigger.setAttribute("aria-expanded","false")}let s=x(this.#k,t);this.#M={anchor:t,trigger:r},r.setAttribute("aria-expanded","true"),this.#v.textContent=`Comment on ${e}`,this.#h.setAttribute("aria-label",`Comment on ${e}`),this.#x.hidden=i===void 0||i==="",this.#x.textContent=i??"",this.#E.value=s?.text??"",this.#g.textContent=s?"empty to delete":"\u2318\u21B5 to save",this.#h.hidden=!1,this.#G(r,n),this.#E.focus(),document.addEventListener("pointerdown",this.#O,!0)}#G(t,e){let r=this.#d.getBoundingClientRect(),n=t.getBoundingClientRect(),i=this.#h.offsetWidth,a=e==="end"?n.right-r.left-i:n.left-r.left,s=Math.min(Math.max(a,0),Math.max(0,r.width-i));this.#h.style.left=`${s}px`,this.#h.style.top=`${n.bottom-r.top+Gt}px`}#R(t=!0){let e=this.#M;this.#M=null,this.#h.hidden=!0,e?.trigger.setAttribute("aria-expanded","false"),document.removeEventListener("pointerdown",this.#O,!0);let r=e!==null&&e.trigger!==this.#o?e.trigger:this.#a;this.#I(),t&&this.#n.contains(r)&&r.focus()}#W(){let t=this.#M;if(t===null)return;let e=this.#u.contains(t.trigger)||this.#m.contains(t.trigger);this.#k=H(this.#k,t.anchor,this.#E.value),this.#R(!e),this.#L(),this.#T||this.#j(),this.#K(),e&&this.#V(t.anchor),this.#P()}#V(t){let e=x(this.#k,t)?.id,r=e===void 0?null:`[data-comment-id="${CSS.escape(e)}"]`,i=(r===null?null:this.#u.querySelector(r)??this.#m.querySelector(r))??this.#a;this.#n.contains(i)&&i.focus()}#O=t=>{if(this.#M===null)return;let e=t.composedPath();e.includes(this.#h)||e.includes(this.#M.trigger)||this.#R()};#U=t=>{if(t.defaultPrevented)return;if(t.key==="Escape"&&this.#M!==null){t.preventDefault(),this.#R();return}if(this.#M!==null||this.#T)return;let e=t.composedPath()[0];if(!(e instanceof HTMLElement&&(e.tagName==="TEXTAREA"||e.tagName==="INPUT"))&&!(t.metaKey||t.ctrlKey||t.altKey)){if(t.key==="j"||t.key==="k"){t.preventDefault(),this.#Y(t.key==="j"?1:-1);return}t.key==="c"&&(t.preventDefault(),this.#X())}};#$(){return Array.from(this.#u.querySelectorAll('[part~="commented"]'))}#Y(t){let e=this.#$();if(e.length===0)return;let r=this.#n.activeElement,n=r instanceof HTMLElement?e.indexOf(r):-1,i=n===-1?t>0?0:e.length-1:n+t;e[Math.min(Math.max(i,0),e.length-1)]?.focus()}#X(){let t=this.#N??this.#D();if(t!==null){this.#N=t,this.#o.hidden=!1,this.#o.style.left=`${t.left}px`,this.#o.style.top=`${t.top}px`,this.#S(t.anchor,q,this.#o,"start",t.anchor.quote);return}let e=this.#n.activeElement;if(e instanceof HTMLElement&&e.dataset.commentId!==void 0){let r=this.#k.find(n=>n.id===e.dataset.commentId);if(r!==void 0){let n=r.anchor.kind==="range"?r.anchor:void 0,i=n===void 0?_:q;this.#S(r.anchor,i,e,"start",n?.quote);return}}this.#S(rt,_,this.#r,"end")}};b("crtr-text",nt);var Zt="M3.25 3.5h9.5A1.75 1.75 0 0 1 14.5 5.25v5A1.75 1.75 0 0 1 12.75 12H7.4l-3.15 2.36A.5.5 0 0 1 3.5 14v-2H3.25A1.75 1.75 0 0 1 1.5 10.25v-5A1.75 1.75 0 0 1 3.25 3.5Z",Qt=`
|
|
540
|
+
`,kt="http://www.w3.org/2000/svg",Lt="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z",Ct=[Lt,"M12 7v6","M9 10h6"],Tt=[Lt,"M13 8H7","M17 12H7"],Yt=["M12 20h9","M16.376 3.622a1 1 0 0 1 3.002 3.002L7.368 18.635a2 2 0 0 1-.855.506l-2.872.838a.5.5 0 0 1-.62-.62l.838-2.872a2 2 0 0 1 .506-.854z","m15 5 3 3"],Xt=["M20 6 9 17l-5-5"];function tt(o){let t=document.createElementNS(kt,"svg");t.setAttribute("viewBox","0 0 24 24"),t.setAttribute("fill","none"),t.setAttribute("stroke","currentColor"),t.setAttribute("stroke-width","2"),t.setAttribute("stroke-linecap","round"),t.setAttribute("stroke-linejoin","round"),t.setAttribute("aria-hidden","true");for(let e of o){let r=document.createElementNS(kt,"path");r.setAttribute("d",e),t.append(r)}return t}function Jt(o){let t=[],e=/\n{2,}/g,r=0,n;for(;(n=e.exec(o))!==null;)t.push({start:r,text:o.slice(r,n.index)}),r=n.index+n[0].length;return t.push({start:r,text:o.slice(r)}),t.filter(i=>i.text.trim().length>0)}function Zt(o,t){let e=t.filter(i=>i.anchor.kind==="range").filter(i=>i.anchor.end>o.start&&i.anchor.start<o.start+o.text.length).sort((i,a)=>i.anchor.start-a.anchor.start),r=[],n=0;for(let i of e){let a=Math.max(n,i.anchor.start-o.start),s=Math.min(o.text.length,i.anchor.end-o.start);s<=a||(a>n&&r.push({text:o.text.slice(n,a)}),r.push({text:o.text.slice(a,s),comment:i}),n=s)}return n<o.text.length&&r.push({text:o.text.slice(n)}),r}function Qt(o){return(o.nodeType===Node.ELEMENT_NODE?o:o.parentElement)?.closest("[data-paragraph]")??null}function te(o,t,e){let r=document.createRange();r.selectNodeContents(o),r.setEnd(t,e);let n=r.cloneContents();for(let i of n.querySelectorAll('[part="comment-bubble"]'))i.remove();return n.textContent?.length??0}function At(o){let t=o.cloneNode(!0);for(let e of t.querySelectorAll('[part="comment-bubble"]'))e.remove();return t.textContent?.length??0}function Mt(o,t,e,r){let n=Array.from(o.querySelectorAll("[data-paragraph]")),i=Qt(t);if(i){if(r==="end"&&e===0){let c=n.indexOf(i),d=n[c-1];if(d)return{paragraph:d,offset:At(d)}}return{paragraph:i,offset:te(i,t,e)}}let a=document.createRange();a.setStart(t,e),a.collapse(!0);let s=r==="start"?n:[...n].reverse();for(let c of s){let d=document.createRange();d.selectNodeContents(c);let u=a.compareBoundaryPoints(r==="start"?Range.START_TO_START:Range.START_TO_END,d);if(r==="start"&&u<=0||r==="end"&&u>=0)return{paragraph:c,offset:r==="start"?0:At(c)}}return null}function ee(o,t){let e=o,r=[typeof e.getSelection=="function"?e.getSelection():null,document.getSelection()];for(let n of r){if(!n||n.isCollapsed||n.rangeCount===0)continue;let i=n.getRangeAt(0);if(t.contains(i.startContainer)&&t.contains(i.endContainer))return i}return null}function et(o){o.setAttribute("aria-haspopup","dialog"),o.setAttribute("aria-controls",St),o.setAttribute("aria-expanded","false")}var st=class extends HTMLElement{#n;#d=document.createElement("div");#s=document.createElement("div");#t=document.createElement("span");#r=document.createElement("button");#e=document.createElement("button");#o=document.createElement("span");#l=document.createElement("div");#c=document.createElement("textarea");#a=document.createElement("div");#u=document.createElement("div");#i=document.createElement("button");#h=document.createElement("div");#x=document.createElement("span");#p=document.createElement("div");#g=document.createElement("div");#w=document.createElement("p");#y=document.createElement("blockquote");#v=document.createElement("textarea");#k=document.createElement("span");#m=document.createElement("button");#A=document.createElement("button");#f={initialText:""};#T;#E="";#b=[];#C=!1;#I=!1;#M=null;#S=null;constructor(){super(),this.#n=this.attachShadow({mode:"open"});let t=document.createElement("style");t.textContent=Ut,this.#d.part.add("container"),this.#s.part.add("toolbar"),this.#t.part.add("edited"),this.#t.textContent="edited",this.#t.hidden=!0,this.#r.type="button",this.#r.part.add("comment-trigger"),this.#r.part.add("whole-comment"),et(this.#r),this.#r.addEventListener("click",()=>{this.#R(at,F,this.#r,"end")}),this.#e.type="button",this.#e.part.add("edit-toggle"),this.#e.hidden=!0,this.#e.append(this.#o),this.#e.addEventListener("click",()=>{this.#C=!this.#C,this.#N(),this.#_(),this.#L(),this.#C?this.#c.focus():this.#a.focus()}),this.#s.append(this.#t,this.#r,this.#e),this.#l.part.add("surface"),this.#c.part.add("editor"),this.#c.addEventListener("input",()=>{this.#E=this.#c.value,this.#L(),this.#P()}),this.#a.part.add("body"),this.#a.tabIndex=0,this.#u.part.add("prose"),this.#i.type="button",this.#i.part.add("comment-trigger"),this.#i.part.add("selection-comment"),this.#i.hidden=!0,et(this.#i),this.#i.append(tt(Ct),document.createTextNode("Comment")),this.#i.addEventListener("mousedown",n=>n.preventDefault()),this.#i.addEventListener("click",()=>{let n=this.#M;n!==null&&this.#R(n.anchor,Y,this.#i,"start",n.anchor.quote)}),this.#a.append(this.#u,this.#i),this.#a.addEventListener("mouseup",()=>this.#V()),this.#h.part.add("comment-rail"),this.#h.hidden=!0,this.#x.part.add("comment-count"),this.#p.part.add("comment-chips"),this.#h.append(this.#x,this.#p),this.#g.part.add("popover"),this.#g.hidden=!0,this.#g.id=St,this.#g.setAttribute("role","dialog"),this.#w.part.add("popover-subject"),this.#y.part.add("popover-quote"),this.#y.hidden=!0,this.#v.part.add("popover-input"),this.#v.placeholder="What should the agent know about this?",this.#v.addEventListener("keydown",n=>{n.key==="Enter"&&(n.metaKey||n.ctrlKey)&&(n.preventDefault(),this.#F())}),this.#k.part.add("popover-hint"),this.#A.type="button",this.#A.part.add("popover-cancel"),this.#A.textContent="Cancel",this.#A.addEventListener("click",()=>this.#H()),this.#m.type="button",this.#m.part.add("popover-save"),this.#m.textContent="Save",this.#m.addEventListener("click",()=>this.#F());let e=document.createElement("div");e.part.add("popover-actions");let r=document.createElement("div");r.part.add("popover-buttons"),r.append(this.#A,this.#m),e.append(this.#k,r),this.#g.append(this.#w,this.#y,this.#v,e),this.#d.append(this.#s,this.#l,this.#h,this.#g),this.#n.append(t,this.#d),this.addEventListener("keydown",this.#Y)}connectedCallback(){if(this.#I)return;let t=k(this);if(t.status!=="ok"){this.#z(t.reason);return}if(typeof t.config.initialText!="string"){this.#z("text config has no initialText string");return}this.#I=!0,this.#f=t.config,this.#T=N(this),this.#E=t.config.initialText,this.#W(),this.#C=t.config.editable===!0&&this.#E.length===0,this.#L(),this.#_(),this.#K()}disconnectedCallback(){document.removeEventListener("pointerdown",this.#O,!0)}#W(){if(this.#T===void 0)return;let t=I(this.#T);t!==void 0&&(this.#f.editable===!0&&typeof t.text=="string"&&(this.#E=t.text),this.#b=H(t.comments))}#B(){return{text:this.#E,edited:this.#E!==this.#f.initialText,comments:this.#b}}#P(){this.#T!==void 0&&$(this.#T,this.#B())}#z(t){let e=document.createElement("div");e.part.add("unavailable"),e.setAttribute("role","status");let r=document.createElement("span");r.part.add("reason"),r.textContent=t,e.append("Text unavailable: ",r),this.#d.replaceChildren(e)}#L(){this.#t.hidden=this.#E===this.#f.initialText;let t=b(this.#b,at);this.#r.replaceChildren(tt(t?Tt:Ct)),this.#r.dataset.state=t?"on":"off",this.#r.setAttribute("aria-label",`${t?"Edit comment on":"Comment on"} ${F}`),this.#e.hidden=this.#f.editable!==!0,this.#e.dataset.state=this.#C?"on":"off",this.#o.textContent=this.#C?"Done":"Edit",this.#e.replaceChildren(tt(this.#C?Xt:Yt),this.#o)}#_(){if(this.#C){this.#c.value!==this.#E&&(this.#c.value=this.#E),this.#c.placeholder=this.#f.placeholder??"Write your answer\u2026",this.#l.firstChild!==this.#c&&this.#l.replaceChildren(this.#c);return}this.#l.firstChild!==this.#a&&this.#l.replaceChildren(this.#a),this.#j()}#j(){let t=Jt(this.#E);if(t.length===0){let r=document.createElement("p");r.part.add("placeholder"),r.textContent=this.#f.placeholder??"Nothing yet.",this.#u.replaceChildren(r);return}let e=t.map(r=>{let n=document.createElement("p");n.dataset.paragraph="",n.dataset.start=String(r.start);for(let i of Zt(r,this.#b))n.append(i.comment?this.#q(i.text,i.comment):i.text);return n});this.#u.replaceChildren(...e)}#q(t,e){let r=document.createElement("span");r.part.add("commented"),r.tabIndex=0,r.dataset.commentId=e.id,et(r);let n=document.createElement("span");n.part.add("comment-bubble"),n.setAttribute("role","note");let i=document.createElement("span");i.part.add("bubble-label"),i.textContent="Comment";let a=document.createElement("span");return a.textContent=e.text,n.append(i,a),r.append(t,n),r}#K(){let t=this.#b.length;if(this.#h.hidden=t===0,t===0){this.#p.replaceChildren();return}this.#x.textContent=`${t} comment${t===1?"":"s"}`;let e=this.#b.map(r=>{let n=document.createElement("button");n.type="button",n.part.add("comment-trigger"),n.part.add("comment-chip"),n.dataset.commentId=r.id,et(n);let i=document.createElement("span");i.textContent=r.text,n.append(tt(Tt),i);let a=r.anchor.kind==="range"?r.anchor:void 0;return n.setAttribute("aria-label",`Edit comment on ${a?Y:F}`),n.addEventListener("click",()=>{this.#R(r.anchor,a?Y:F,n,"start",a?.quote)}),n});this.#p.replaceChildren(...e)}#D(){let t=ee(this.#n,this.#a);if(t===null)return null;let e=Mt(this.#a,t.startContainer,t.startOffset,"start"),r=Mt(this.#a,t.endContainer,t.endOffset,"end");if(e===null||r===null||e.paragraph!==r.paragraph)return null;let n=Number(e.paragraph.dataset.start??"0"),i=n+e.offset,a=n+r.offset;if(a<=i)return null;let s=t.getBoundingClientRect(),c=this.#a.getBoundingClientRect();return{anchor:{kind:"range",start:i,end:a,quote:this.#E.slice(i,a)},left:s.left-c.left,top:s.bottom-c.top+4}}#V(){if(this.#C||this.#S!==null)return;let t=this.#D();if(t===null){this.#N();return}this.#M=t,this.#i.hidden=!1,this.#i.style.left=`${t.left}px`,this.#i.style.top=`${t.top}px`}#N(){this.#M=null,this.#i.hidden=!0}#R(t,e,r,n,i){let a=this.#S;if(a!==null){if(a.trigger===r){this.#H();return}a.trigger.setAttribute("aria-expanded","false")}let s=b(this.#b,t);this.#S={anchor:t,trigger:r},r.setAttribute("aria-expanded","true"),this.#w.textContent=`Comment on ${e}`,this.#g.setAttribute("aria-label",`Comment on ${e}`),this.#y.hidden=i===void 0||i==="",this.#y.textContent=i??"",this.#v.value=s?.text??"",this.#k.textContent=s?"empty to delete":"\u2318\u21B5 to save",this.#g.hidden=!1,this.#G(r,n),this.#v.focus(),document.addEventListener("pointerdown",this.#O,!0)}#G(t,e){let r=this.#d.getBoundingClientRect(),n=t.getBoundingClientRect(),i=this.#g.offsetWidth,a=e==="end"?n.right-r.left-i:n.left-r.left,s=Math.min(Math.max(a,0),Math.max(0,r.width-i));this.#g.style.left=`${s}px`,this.#g.style.top=`${n.bottom-r.top+Vt}px`}#H(t=!0){let e=this.#S;this.#S=null,this.#g.hidden=!0,e?.trigger.setAttribute("aria-expanded","false"),document.removeEventListener("pointerdown",this.#O,!0);let r=e!==null&&e.trigger!==this.#i?e.trigger:this.#a;this.#N(),t&&this.#n.contains(r)&&r.focus()}#F(){let t=this.#S;if(t===null)return;let e=this.#u.contains(t.trigger)||this.#p.contains(t.trigger);this.#b=R(this.#b,t.anchor,this.#v.value),this.#H(!e),this.#L(),this.#C||this.#j(),this.#K(),e&&this.#U(t.anchor),this.#P()}#U(t){let e=b(this.#b,t)?.id,r=e===void 0?null:`[data-comment-id="${CSS.escape(e)}"]`,i=(r===null?null:this.#u.querySelector(r)??this.#p.querySelector(r))??this.#a;this.#n.contains(i)&&i.focus()}#O=t=>{if(this.#S===null)return;let e=t.composedPath();e.includes(this.#g)||e.includes(this.#S.trigger)||this.#H()};#Y=t=>{if(t.defaultPrevented)return;if(t.key==="Escape"&&this.#S!==null){t.preventDefault(),this.#H();return}if(this.#S!==null||this.#C)return;let e=t.composedPath()[0];if(!(e instanceof HTMLElement&&(e.tagName==="TEXTAREA"||e.tagName==="INPUT"))&&!(t.metaKey||t.ctrlKey||t.altKey)){if(t.key==="j"||t.key==="k"){t.preventDefault(),this.#X(t.key==="j"?1:-1);return}t.key==="c"&&(t.preventDefault(),this.#J())}};#$(){return Array.from(this.#u.querySelectorAll('[part~="commented"]'))}#X(t){let e=this.#$();if(e.length===0)return;let r=this.#n.activeElement,n=r instanceof HTMLElement?e.indexOf(r):-1,i=n===-1?t>0?0:e.length-1:n+t;e[Math.min(Math.max(i,0),e.length-1)]?.focus()}#J(){let t=this.#M??this.#D();if(t!==null){this.#M=t,this.#i.hidden=!1,this.#i.style.left=`${t.left}px`,this.#i.style.top=`${t.top}px`,this.#R(t.anchor,Y,this.#i,"start",t.anchor.quote);return}let e=this.#n.activeElement;if(e instanceof HTMLElement&&e.dataset.commentId!==void 0){let r=this.#b.find(n=>n.id===e.dataset.commentId);if(r!==void 0){let n=r.anchor.kind==="range"?r.anchor:void 0,i=n===void 0?F:Y;this.#R(r.anchor,i,e,"start",n?.quote);return}}this.#R(at,F,this.#r,"end")}};v("crtr-text",st);var re="M3.25 3.5h9.5A1.75 1.75 0 0 1 14.5 5.25v5A1.75 1.75 0 0 1 12.75 12H7.4l-3.15 2.36A.5.5 0 0 1 3.5 14v-2H3.25A1.75 1.75 0 0 1 1.5 10.25v-5A1.75 1.75 0 0 1 3.25 3.5Z",ne=`
|
|
541
541
|
:host {
|
|
542
542
|
display: block;
|
|
543
543
|
}
|
|
@@ -827,7 +827,7 @@
|
|
|
827
827
|
color: var(--crtr-color-text-muted);
|
|
828
828
|
text-align: center;
|
|
829
829
|
}
|
|
830
|
-
`;function te(o){return o==null?"":typeof o=="string"?o:String(o)}function ot(o){return typeof o=="object"&&o!==null&&!Array.isArray(o)}function ee(o){let t=Array.isArray(o)?o:ot(o)&&Array.isArray(o.rows)?o.rows:void 0;if(t===void 0)return{status:"invalid",reason:"source data is not a list of rows"};let e=[];for(let r=0;r<t.length;r+=1){let n=t[r];if(!ot(n)||typeof n.id!="string"||n.id===""||!ot(n.cells))return{status:"invalid",reason:`source row #${r} is not { id, cells }`};let i={};for(let[a,s]of Object.entries(n.cells))if(s!==void 0){if(s!==null&&typeof s!="string"&&typeof s!="number"&&typeof s!="boolean")return{status:"invalid",reason:`source row "${n.id}" cell "${a}" is not a string, number, boolean or null`};i[a]=s}e.push({id:n.id,cells:i})}return{status:"ok",rows:e}}function re(){let o=document.createElementNS("http://www.w3.org/2000/svg","svg");o.setAttribute("viewBox","0 0 16 16"),o.setAttribute("aria-hidden","true"),o.setAttribute("focusable","false");let t=document.createElementNS("http://www.w3.org/2000/svg","path");return t.setAttribute("d",Zt),t.setAttribute("fill","none"),t.setAttribute("stroke","currentColor"),t.setAttribute("stroke-width","1.25"),t.setAttribute("stroke-linejoin","round"),o.append(t),o}function ne(o){return o instanceof HTMLElement?o.closest('input[type="text"], textarea, [contenteditable="true"]')!==null:!1}var it=class extends HTMLElement{#n;#d;#c;#t=[];#r=[];#e=[];#i=[];#l=null;#s=null;#a;#u=!1;#o;#p;#f;#m;#h;#v;#x=new Map;#E=new Map;#g;constructor(){super(),this.#n=this.attachShadow({mode:"open"})}connectedCallback(){this.#u=!0;let t=C(this);if(t.status!=="ok"){this.#L(t.reason);return}let e=t.config;if(!Array.isArray(e.columns)||e.columns.length===0){this.#L("table config has no columns");return}if(e.rows!==void 0&&e.source!==void 0){this.#L("table rows and source are mutually exclusive");return}if(this.#c=e,this.#d=$(this),e.source!==void 0){this.#_("Loading table data\u2026"),this.#w(e.source);return}if(!Array.isArray(e.rows)){this.#L("table config has neither rows nor source");return}this.#t=e.rows,this.#j()}disconnectedCallback(){this.#u=!1}async#w(t){let e=await P(t);if(!this.#u)return;if(e.status!=="ok"){this.#L(`table source "${t}" is ${e.status}: ${e.reason}`);return}let r=ee(e.data);if(r.status!=="ok"){this.#L(`table source "${t}": ${r.reason}`);return}this.#t=r.rows,this.#j()}get#y(){return this.#c?.rowSelect??"none"}get#C(){return this.#c?.columnSelect??"none"}#A(){return{selectedRowIds:[...this.#r],selectedColumnIds:[...this.#e],comments:[...this.#i]}}#b(){this.#$(),this.#d!==void 0&&R(this.#d,this.#A())}#k(t){return this.#t.map(e=>e.id).filter(e=>t.includes(e))}#T(t){return(this.#c?.columns??[]).map(e=>e.id).filter(e=>t.includes(e))}#H(t,e){let r=this.#y;r!=="none"&&(r==="single"?this.#r=e?[t]:[]:this.#r=this.#k(e?[...this.#r,t]:this.#r.filter(n=>n!==t)),this.#b())}#N(t){if(this.#y==="single"){this.#H(t,!0);return}this.#H(t,!this.#r.includes(t))}#M(t,e){let r=this.#C;r!=="none"&&(r==="single"?this.#e=e?[t]:[]:this.#e=this.#T(e?[...this.#e,t]:this.#e.filter(n=>n!==t)),this.#b())}#B(t){this.#M(t,!this.#e.includes(t))}#P(t){this.#y==="multi"&&(this.#r=t?this.#t.map(e=>e.id):[],this.#b())}#z(){this.#n.replaceChildren(),this.#x.clear(),this.#E.clear(),this.#o=void 0,this.#p=void 0,this.#a=void 0,this.#s=null,this.#v=void 0,this.#g=void 0;let t=document.createElement("style");t.textContent=Qt,this.#n.append(t)}#L(t){this.#z();let e=document.createElement("div");e.part.add("unavailable"),e.setAttribute("role","status");let r=document.createElement("span");r.part.add("reason"),r.textContent=t,e.append("Table unavailable: ",r),this.#n.append(e)}#_(t){this.#z();let e=document.createElement("div");e.part.add("status"),e.setAttribute("role","status"),e.textContent=t,this.#n.append(e)}#j(){let t=this.#c;if(t===void 0)return;this.#z();let e=document.createElement("div");e.part.add("container"),e.tabIndex=0,e.addEventListener("keydown",n=>this.#V(n)),e.addEventListener("focus",()=>{this.#l===null&&this.#t.length>0&&(this.#l=this.#t[0].id,this.#$())}),this.#o=e;let r=document.createElement("table");if(r.part.add("table"),t.caption!==void 0&&t.caption!==""){let n=document.createElement("caption");n.part.add("caption"),n.textContent=t.caption,r.append(n)}if(r.append(this.#F(t),this.#K(t)),e.append(r),this.#t.length===0){let n=document.createElement("div");n.part.add("empty"),n.textContent="No rows.",e.append(n)}e.append(this.#q()),this.#n.append(e),this.#$()}#F(t){let e=document.createElement("thead"),r=document.createElement("tr");if(r.part.add("header-row"),this.#y!=="none"){let i=document.createElement("th");if(i.part.add("select-head"),i.setAttribute("scope","col"),this.#y==="multi"){let a=document.createElement("input");a.type="checkbox",a.part.add("select-all"),a.setAttribute("aria-label","Select every row"),a.addEventListener("change",()=>this.#P(a.checked)),this.#v=a,i.append(a)}r.append(i)}for(let i of t.columns){let a=document.createElement("th");a.part.add("column-header"),a.setAttribute("scope","col"),a.dataset.columnHeader=i.id,i.align==="right"&&(a.dataset.align="right");let s=document.createElement("span");s.part.add("header-cell-inner");let c;if(this.#C==="none"){let u=document.createElement("span");u.textContent=i.label,s.append(u)}else c=document.createElement("button"),c.type="button",c.part.add("column-toggle"),c.dataset.columnToggle=i.id,c.setAttribute("aria-pressed","false"),c.setAttribute("aria-label",`Select the ${i.label} column`),c.textContent=i.label,c.addEventListener("click",()=>this.#B(i.id)),s.append(c);let d=this.#D({kind:"column",columnId:i.id},`the ${i.label} column`);s.append(d),a.append(s),r.append(a),this.#E.set(i.id,{toggle:c,comment:d,cells:[],head:a})}let n=document.createElement("th");return n.part.add("comment-head"),n.setAttribute("scope","col"),this.#g=this.#D({kind:"whole"},"this table"),n.append(this.#g),r.append(n),e.append(r),e}#K(t){let e=document.createElement("tbody");for(let r of this.#t){let n=document.createElement("tr");n.part.add("row"),n.dataset.rowId=r.id,n.tabIndex=-1,n.addEventListener("mouseenter",()=>this.#R(r.id)),n.addEventListener("focusin",()=>this.#R(r.id));let i;if(this.#y!=="none"){let c=document.createElement("td");c.part.add("select-cell");let d=document.createElement("input");d.type=this.#y==="single"?"radio":"checkbox",d.part.add("row-control"),this.#y==="single"&&(d.name=`${this.#d??"crtr-table"}-row`),d.value=r.id,d.setAttribute("aria-label",`Select row ${r.id}`),d.addEventListener("change",()=>this.#H(r.id,d.checked)),i=d,c.append(d),n.append(c)}for(let c of t.columns){let d=document.createElement("td");d.part.add("cell"),d.dataset.columnId=c.id,c.align==="right"&&(d.dataset.align="right"),c.mono===!0&&(d.dataset.mono="true"),d.textContent=te(r.cells[c.id]),n.append(d),this.#E.get(c.id)?.cells.push(d)}let a=document.createElement("td");a.part.add("comment-cell");let s=this.#D({kind:"row",rowId:r.id},`row ${r.id}`);a.append(s),n.append(a),e.append(n),this.#x.set(r.id,{tr:n,...i===void 0?{}:{control:i},comment:s})}return e}#D(t,e){let r=document.createElement("button");return r.type="button",r.part.add("comment-trigger"),r.setAttribute("aria-label",`Comment on ${e}`),r.dataset.commentTarget=e,r.append(re()),r.addEventListener("click",()=>this.#I(t,r)),r}#q(){let t=document.createElement("div");t.part.add("comment-editor"),t.hidden=!0,t.setAttribute("role","dialog"),t.setAttribute("aria-label","Comment");let e=document.createElement("p");e.part.add("comment-target"),t.append(e);let r=document.createElement("textarea");r.part.add("comment-input"),r.placeholder="What should the agent know about this?",r.addEventListener("keydown",d=>{d.key==="Enter"&&(d.metaKey||d.ctrlKey)?(d.preventDefault(),this.#G()):d.key==="Escape"&&(d.preventDefault(),this.#S())}),t.append(r);let n=document.createElement("div");n.part.add("comment-actions");let i=document.createElement("span");i.part.add("comment-hint"),n.append(i);let a=document.createElement("span"),s=document.createElement("button");s.type="button",s.part.add("comment-cancel"),s.textContent="Cancel",s.addEventListener("click",()=>this.#S());let c=document.createElement("button");return c.type="button",c.part.add("comment-save"),c.textContent="Save",c.addEventListener("click",()=>this.#G()),a.append(s," ",c),n.append(a),t.append(n),this.#p=t,this.#f=e,this.#m=r,this.#h=i,t}#I(t,e){let r=this.#p,n=this.#o;if(r===void 0||n===void 0)return;this.#s=t,this.#a=e;let i=x(this.#i,t);this.#m!==void 0&&(this.#m.value=i?.text??""),this.#f!==void 0&&(this.#f.textContent=`Comment on ${e.dataset.commentTarget??Z(t)}`),this.#h!==void 0&&(this.#h.textContent=i===void 0?"\u2318\u21B5 to save":"empty to delete");let a=n.getBoundingClientRect(),s=e.getBoundingClientRect();r.hidden=!1,r.style.top=`${Math.max(0,s.bottom-a.top+4)}px`,r.style.right=`${Math.max(0,a.right-s.right)}px`,this.#$(),this.#m?.focus()}#S(){let t=this.#a;this.#s=null,this.#a=void 0,this.#p!==void 0&&(this.#p.hidden=!0),this.#$(),t?.focus()}#G(){let t=this.#s;t!==null&&(this.#i=H(this.#i,t,this.#m?.value??""),this.#S(),this.#b())}#R(t){this.#l!==t&&(this.#l=t,this.#$())}#W(t){let e=this.#x.get(t);(e?.control??e?.tr)?.focus()}#V(t){if(t.metaKey||t.ctrlKey||t.altKey)return;let e=t.composedPath()[0]??t.target;if(ne(e))return;let r=t.key.toLowerCase();if(r!=="j"&&r!=="k"&&r!=="x"&&r!=="c")return;let n=e instanceof HTMLElement?e.closest("[data-column-header]")?.dataset.columnHeader:void 0;if(n!==void 0&&(r==="x"||r==="c")){if(t.preventDefault(),r==="x")this.#B(n);else{let c=this.#E.get(n);c!==void 0&&this.#I({kind:"column",columnId:n},c.comment)}return}let i=this.#t.map(c=>c.id);if(i.length===0)return;let a=this.#l??this.#r[this.#r.length-1]??i[0];if(r==="j"||r==="k"){t.preventDefault();let c=Math.max(0,i.indexOf(a)),d=i[(c+(r==="j"?1:-1)+i.length)%i.length];this.#R(d),this.#W(d);return}if(t.preventDefault(),r==="x"){this.#N(a);return}let s=this.#x.get(a);s!==void 0&&this.#I({kind:"row",rowId:a},s.comment)}#O(t,e){let r=x(this.#i,e),n=t.dataset.commentTarget??Z(e);t.dataset.hasComment=r===void 0?"false":"true",t.setAttribute("aria-label",r===void 0?`Comment on ${n}`:`Edit comment on ${n}`),t.title=r?.text??"",t.querySelector("path")?.setAttribute("fill",r===void 0?"none":"currentColor"),t.dataset.open=this.#U(e)?"true":"false"}#U(t){let e=this.#s;return e===null||e.kind!==t.kind?!1:e.kind==="row"&&t.kind==="row"?e.rowId===t.rowId:e.kind==="column"&&t.kind==="column"?e.columnId===t.columnId:e.kind==="whole"}#$(){for(let[t,e]of this.#x){let r=this.#r.includes(t);r?e.tr.dataset.state="selected":delete e.tr.dataset.state,e.tr.dataset.active=this.#l===t?"true":"false",e.tr.setAttribute("aria-selected",r?"true":"false"),e.control!==void 0&&(e.control.checked=r),this.#O(e.comment,{kind:"row",rowId:t})}for(let[t,e]of this.#E){let r=this.#e.includes(t);e.toggle?.setAttribute("aria-pressed",r?"true":"false"),e.head.dataset.columnSelected=r?"true":"false";for(let n of e.cells)n.dataset.columnSelected=r?"true":"false";this.#O(e.comment,{kind:"column",columnId:t})}if(this.#g!==void 0&&this.#O(this.#g,{kind:"whole"}),this.#v!==void 0){let t=this.#t.length>0&&this.#r.length===this.#t.length;this.#v.checked=t,this.#v.indeterminate=this.#r.length>0&&!t}}};b("crtr-table",it);var oe=`
|
|
830
|
+
`;function oe(o){return o==null?"":typeof o=="string"?o:String(o)}function ct(o){return typeof o=="object"&&o!==null&&!Array.isArray(o)}function ie(o){let t=Array.isArray(o)?o:ct(o)&&Array.isArray(o.rows)?o.rows:void 0;if(t===void 0)return{status:"invalid",reason:"source data is not a list of rows"};let e=[];for(let r=0;r<t.length;r+=1){let n=t[r];if(!ct(n)||typeof n.id!="string"||n.id===""||!ct(n.cells))return{status:"invalid",reason:`source row #${r} is not { id, cells }`};let i={};for(let[a,s]of Object.entries(n.cells))if(s!==void 0){if(s!==null&&typeof s!="string"&&typeof s!="number"&&typeof s!="boolean")return{status:"invalid",reason:`source row "${n.id}" cell "${a}" is not a string, number, boolean or null`};i[a]=s}e.push({id:n.id,cells:i})}return{status:"ok",rows:e}}function ae(){let o=document.createElementNS("http://www.w3.org/2000/svg","svg");o.setAttribute("viewBox","0 0 16 16"),o.setAttribute("aria-hidden","true"),o.setAttribute("focusable","false");let t=document.createElementNS("http://www.w3.org/2000/svg","path");return t.setAttribute("d",re),t.setAttribute("fill","none"),t.setAttribute("stroke","currentColor"),t.setAttribute("stroke-width","1.25"),t.setAttribute("stroke-linejoin","round"),o.append(t),o}function se(o){return o instanceof HTMLElement?o.closest('input[type="text"], textarea, [contenteditable="true"]')!==null:!1}var dt=class extends HTMLElement{#n;#d;#s;#t=[];#r=[];#e=[];#o=[];#l=null;#c=null;#a;#u=!1;#i;#h;#x;#p;#g;#w;#y=new Map;#v=new Map;#k;constructor(){super(),this.#n=this.attachShadow({mode:"open"})}connectedCallback(){this.#u=!0;let t=k(this);if(t.status!=="ok"){this.#L(t.reason);return}let e=t.config;if(!Array.isArray(e.columns)||e.columns.length===0){this.#L("table config has no columns");return}if(e.rows!==void 0&&e.source!==void 0){this.#L("table rows and source are mutually exclusive");return}if(this.#s=e,this.#d=N(this),e.source!==void 0){this.#_("Loading table data\u2026"),this.#m(e.source);return}if(!Array.isArray(e.rows)){this.#L("table config has neither rows nor source");return}this.#t=e.rows,this.#A(),this.#j()}disconnectedCallback(){this.#u=!1}async#m(t){let e=await G(t);if(!this.#u)return;if(e.status!=="ok"){this.#L(`table source "${t}" is ${e.status}: ${e.reason}`);return}let r=ie(e.data);if(r.status!=="ok"){this.#L(`table source "${t}": ${r.reason}`);return}this.#t=r.rows,this.#A(),this.#j()}#A(){if(this.#d===void 0)return;let t=I(this.#d);if(t===void 0)return;let e=this.#C(B(t.selectedRowIds)),r=this.#I(B(t.selectedColumnIds));this.#r=this.#f==="none"?[]:this.#f==="single"?e.slice(0,1):e,this.#e=this.#T==="none"?[]:this.#T==="single"?r.slice(0,1):r;let n=new Set(this.#t.map(a=>a.id)),i=new Set((this.#s?.columns??[]).map(a=>a.id));this.#o=H(t.comments).filter(a=>a.anchor.kind==="row"?n.has(a.anchor.rowId):a.anchor.kind==="column"?i.has(a.anchor.columnId):!0)}get#f(){return this.#s?.rowSelect??"none"}get#T(){return this.#s?.columnSelect??"none"}#E(){return{selectedRowIds:[...this.#r],selectedColumnIds:[...this.#e],comments:[...this.#o]}}#b(){this.#$(),this.#d!==void 0&&$(this.#d,this.#E())}#C(t){return this.#t.map(e=>e.id).filter(e=>t.includes(e))}#I(t){return(this.#s?.columns??[]).map(e=>e.id).filter(e=>t.includes(e))}#M(t,e){let r=this.#f;r!=="none"&&(r==="single"?this.#r=e?[t]:[]:this.#r=this.#C(e?[...this.#r,t]:this.#r.filter(n=>n!==t)),this.#b())}#S(t){if(this.#f==="single"){this.#M(t,!0);return}this.#M(t,!this.#r.includes(t))}#W(t,e){let r=this.#T;r!=="none"&&(r==="single"?this.#e=e?[t]:[]:this.#e=this.#I(e?[...this.#e,t]:this.#e.filter(n=>n!==t)),this.#b())}#B(t){this.#W(t,!this.#e.includes(t))}#P(t){this.#f==="multi"&&(this.#r=t?this.#t.map(e=>e.id):[],this.#b())}#z(){this.#n.replaceChildren(),this.#y.clear(),this.#v.clear(),this.#i=void 0,this.#h=void 0,this.#a=void 0,this.#c=null,this.#w=void 0,this.#k=void 0;let t=document.createElement("style");t.textContent=ne,this.#n.append(t)}#L(t){this.#z();let e=document.createElement("div");e.part.add("unavailable"),e.setAttribute("role","status");let r=document.createElement("span");r.part.add("reason"),r.textContent=t,e.append("Table unavailable: ",r),this.#n.append(e)}#_(t){this.#z();let e=document.createElement("div");e.part.add("status"),e.setAttribute("role","status"),e.textContent=t,this.#n.append(e)}#j(){let t=this.#s;if(t===void 0)return;this.#z();let e=document.createElement("div");e.part.add("container"),e.tabIndex=0,e.addEventListener("keydown",n=>this.#U(n)),e.addEventListener("focus",()=>{this.#l===null&&this.#t.length>0&&(this.#l=this.#t[0].id,this.#$())}),this.#i=e;let r=document.createElement("table");if(r.part.add("table"),t.caption!==void 0&&t.caption!==""){let n=document.createElement("caption");n.part.add("caption"),n.textContent=t.caption,r.append(n)}if(r.append(this.#q(t),this.#K(t)),e.append(r),this.#t.length===0){let n=document.createElement("div");n.part.add("empty"),n.textContent="No rows.",e.append(n)}e.append(this.#V()),this.#n.append(e),this.#$()}#q(t){let e=document.createElement("thead"),r=document.createElement("tr");if(r.part.add("header-row"),this.#f!=="none"){let i=document.createElement("th");if(i.part.add("select-head"),i.setAttribute("scope","col"),this.#f==="multi"){let a=document.createElement("input");a.type="checkbox",a.part.add("select-all"),a.setAttribute("aria-label","Select every row"),a.addEventListener("change",()=>this.#P(a.checked)),this.#w=a,i.append(a)}r.append(i)}for(let i of t.columns){let a=document.createElement("th");a.part.add("column-header"),a.setAttribute("scope","col"),a.dataset.columnHeader=i.id,i.align==="right"&&(a.dataset.align="right");let s=document.createElement("span");s.part.add("header-cell-inner");let c;if(this.#T==="none"){let u=document.createElement("span");u.textContent=i.label,s.append(u)}else c=document.createElement("button"),c.type="button",c.part.add("column-toggle"),c.dataset.columnToggle=i.id,c.setAttribute("aria-pressed","false"),c.setAttribute("aria-label",`Select the ${i.label} column`),c.textContent=i.label,c.addEventListener("click",()=>this.#B(i.id)),s.append(c);let d=this.#D({kind:"column",columnId:i.id},`the ${i.label} column`);s.append(d),a.append(s),r.append(a),this.#v.set(i.id,{toggle:c,comment:d,cells:[],head:a})}let n=document.createElement("th");return n.part.add("comment-head"),n.setAttribute("scope","col"),this.#k=this.#D({kind:"whole"},"this table"),n.append(this.#k),r.append(n),e.append(r),e}#K(t){let e=document.createElement("tbody");for(let r of this.#t){let n=document.createElement("tr");n.part.add("row"),n.dataset.rowId=r.id,n.tabIndex=-1,n.addEventListener("mouseenter",()=>this.#H(r.id)),n.addEventListener("focusin",()=>this.#H(r.id));let i;if(this.#f!=="none"){let c=document.createElement("td");c.part.add("select-cell");let d=document.createElement("input");d.type=this.#f==="single"?"radio":"checkbox",d.part.add("row-control"),this.#f==="single"&&(d.name=`${this.#d??"crtr-table"}-row`),d.value=r.id,d.setAttribute("aria-label",`Select row ${r.id}`),d.addEventListener("change",()=>this.#M(r.id,d.checked)),i=d,c.append(d),n.append(c)}for(let c of t.columns){let d=document.createElement("td");d.part.add("cell"),d.dataset.columnId=c.id,c.align==="right"&&(d.dataset.align="right"),c.mono===!0&&(d.dataset.mono="true"),d.textContent=oe(r.cells[c.id]),n.append(d),this.#v.get(c.id)?.cells.push(d)}let a=document.createElement("td");a.part.add("comment-cell");let s=this.#D({kind:"row",rowId:r.id},`row ${r.id}`);a.append(s),n.append(a),e.append(n),this.#y.set(r.id,{tr:n,...i===void 0?{}:{control:i},comment:s})}return e}#D(t,e){let r=document.createElement("button");return r.type="button",r.part.add("comment-trigger"),r.setAttribute("aria-label",`Comment on ${e}`),r.dataset.commentTarget=e,r.append(ae()),r.addEventListener("click",()=>this.#N(t,r)),r}#V(){let t=document.createElement("div");t.part.add("comment-editor"),t.hidden=!0,t.setAttribute("role","dialog"),t.setAttribute("aria-label","Comment");let e=document.createElement("p");e.part.add("comment-target"),t.append(e);let r=document.createElement("textarea");r.part.add("comment-input"),r.placeholder="What should the agent know about this?",r.addEventListener("keydown",d=>{d.key==="Enter"&&(d.metaKey||d.ctrlKey)?(d.preventDefault(),this.#G()):d.key==="Escape"&&(d.preventDefault(),this.#R())}),t.append(r);let n=document.createElement("div");n.part.add("comment-actions");let i=document.createElement("span");i.part.add("comment-hint"),n.append(i);let a=document.createElement("span"),s=document.createElement("button");s.type="button",s.part.add("comment-cancel"),s.textContent="Cancel",s.addEventListener("click",()=>this.#R());let c=document.createElement("button");return c.type="button",c.part.add("comment-save"),c.textContent="Save",c.addEventListener("click",()=>this.#G()),a.append(s," ",c),n.append(a),t.append(n),this.#h=t,this.#x=e,this.#p=r,this.#g=i,t}#N(t,e){let r=this.#h,n=this.#i;if(r===void 0||n===void 0)return;this.#c=t,this.#a=e;let i=b(this.#o,t);this.#p!==void 0&&(this.#p.value=i?.text??""),this.#x!==void 0&&(this.#x.textContent=`Comment on ${e.dataset.commentTarget??nt(t)}`),this.#g!==void 0&&(this.#g.textContent=i===void 0?"\u2318\u21B5 to save":"empty to delete");let a=n.getBoundingClientRect(),s=e.getBoundingClientRect();r.hidden=!1,r.style.top=`${Math.max(0,s.bottom-a.top+4)}px`,r.style.right=`${Math.max(0,a.right-s.right)}px`,this.#$(),this.#p?.focus()}#R(){let t=this.#a;this.#c=null,this.#a=void 0,this.#h!==void 0&&(this.#h.hidden=!0),this.#$(),t?.focus()}#G(){let t=this.#c;t!==null&&(this.#o=R(this.#o,t,this.#p?.value??""),this.#R(),this.#b())}#H(t){this.#l!==t&&(this.#l=t,this.#$())}#F(t){let e=this.#y.get(t);(e?.control??e?.tr)?.focus()}#U(t){if(t.metaKey||t.ctrlKey||t.altKey)return;let e=t.composedPath()[0]??t.target;if(se(e))return;let r=t.key.toLowerCase();if(r!=="j"&&r!=="k"&&r!=="x"&&r!=="c")return;let n=e instanceof HTMLElement?e.closest("[data-column-header]")?.dataset.columnHeader:void 0;if(n!==void 0&&(r==="x"||r==="c")){if(t.preventDefault(),r==="x")this.#B(n);else{let c=this.#v.get(n);c!==void 0&&this.#N({kind:"column",columnId:n},c.comment)}return}let i=this.#t.map(c=>c.id);if(i.length===0)return;let a=this.#l??this.#r[this.#r.length-1]??i[0];if(r==="j"||r==="k"){t.preventDefault();let c=Math.max(0,i.indexOf(a)),d=i[(c+(r==="j"?1:-1)+i.length)%i.length];this.#H(d),this.#F(d);return}if(t.preventDefault(),r==="x"){this.#S(a);return}let s=this.#y.get(a);s!==void 0&&this.#N({kind:"row",rowId:a},s.comment)}#O(t,e){let r=b(this.#o,e),n=t.dataset.commentTarget??nt(e);t.dataset.hasComment=r===void 0?"false":"true",t.setAttribute("aria-label",r===void 0?`Comment on ${n}`:`Edit comment on ${n}`),t.title=r?.text??"",t.querySelector("path")?.setAttribute("fill",r===void 0?"none":"currentColor"),t.dataset.open=this.#Y(e)?"true":"false"}#Y(t){let e=this.#c;return e===null||e.kind!==t.kind?!1:e.kind==="row"&&t.kind==="row"?e.rowId===t.rowId:e.kind==="column"&&t.kind==="column"?e.columnId===t.columnId:e.kind==="whole"}#$(){for(let[t,e]of this.#y){let r=this.#r.includes(t);r?e.tr.dataset.state="selected":delete e.tr.dataset.state,e.tr.dataset.active=this.#l===t?"true":"false",e.tr.setAttribute("aria-selected",r?"true":"false"),e.control!==void 0&&(e.control.checked=r),this.#O(e.comment,{kind:"row",rowId:t})}for(let[t,e]of this.#v){let r=this.#e.includes(t);e.toggle?.setAttribute("aria-pressed",r?"true":"false"),e.head.dataset.columnSelected=r?"true":"false";for(let n of e.cells)n.dataset.columnSelected=r?"true":"false";this.#O(e.comment,{kind:"column",columnId:t})}if(this.#k!==void 0&&this.#O(this.#k,{kind:"whole"}),this.#w!==void 0){let t=this.#t.length>0&&this.#r.length===this.#t.length;this.#w.checked=t,this.#w.indeterminate=this.#r.length>0&&!t}}};v("crtr-table",dt);var ce=`
|
|
831
831
|
:host {
|
|
832
832
|
display: block;
|
|
833
833
|
/* Column count answers the element's own width, not the viewport: a slot can sit in
|
|
@@ -1096,7 +1096,7 @@
|
|
|
1096
1096
|
margin-top: var(--crtr-space-1);
|
|
1097
1097
|
font-size: calc(var(--crtr-font-size) * 0.85);
|
|
1098
1098
|
}
|
|
1099
|
-
`,
|
|
1099
|
+
`,de=new Set(["id","title","subtitle","body","tag"]);function le(o){if(o===null||typeof o!="object"||Array.isArray(o))return null;let t=o;if(typeof t.id!="string"||t.id===""||typeof t.title!="string"||t.title==="")return null;for(let e of["subtitle","body","tag"])if(t[e]!==void 0&&typeof t[e]!="string")return null;for(let e of Object.keys(t))if(!de.has(e))return null;return{id:t.id,title:t.title,subtitle:t.subtitle,body:t.body,tag:t.tag}}function Ht(o){if(!Array.isArray(o))return null;let t=[],e=new Set;for(let r of o){let n=le(r);if(n===null||e.has(n.id))return null;e.add(n.id),t.push(n)}return t}var ue=new Set(["cards","source","mode","columns"]);function pe(o){for(let i of Object.keys(o))if(!ue.has(i))return{status:"invalid",reason:`unknown config property "${i}"`};let t=o.mode;if(t!=="single"&&t!=="multi")return{status:"invalid",reason:'mode must be "single" or "multi"'};let e=o.source;if(e!==void 0&&typeof e!="string")return{status:"invalid",reason:"source must be a string"};let r=o.columns;if(r!==void 0&&r!==2&&r!==3)return{status:"invalid",reason:"columns must be 2 or 3"};let n;if(o.cards!==void 0){if(e!==void 0)return{status:"invalid",reason:"cards and source are mutually exclusive"};let i=Ht(o.cards);if(i===null)return{status:"invalid",reason:"cards must be a list of uniquely identified cards"};n=i}return{status:"ok",config:{cards:n,source:e,mode:t,columns:r}}}function me(o){return o instanceof HTMLTextAreaElement||o instanceof HTMLElement&&o.isContentEditable?!0:o instanceof HTMLInputElement?o.type!=="checkbox"&&o.type!=="radio":!1}var lt="http://www.w3.org/2000/svg";function he(o){let t=document.createElementNS(lt,"svg");t.setAttribute("viewBox","0 0 24 24"),t.setAttribute("fill","none"),t.setAttribute("stroke","currentColor"),t.setAttribute("stroke-width","2"),t.setAttribute("stroke-linecap","round"),t.setAttribute("stroke-linejoin","round"),t.setAttribute("aria-hidden","true");let e=document.createElementNS(lt,"path");e.setAttribute("d","M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"),t.append(e);let r=o?[["7","9","17","9"],["7","13","13","13"]]:[["12","7","12","13"],["9","10","15","10"]];for(let[n,i,a,s]of r){let c=document.createElementNS(lt,"line");c.setAttribute("x1",n??"0"),c.setAttribute("y1",i??"0"),c.setAttribute("x2",a??"0"),c.setAttribute("y2",s??"0"),t.append(c)}return t}var Rt=0,ut=class extends HTMLElement{#n=document.createElement("div");#d;#s=null;#t=[];#r;#e=[];#o=[];#l=null;#c=new Map;#a=null;#u=null;#i=0;constructor(){super(),Rt+=1,this.#d=`crtr-cards-${Rt}`;let t=this.attachShadow({mode:"open"}),e=document.createElement("style");e.textContent=ce,this.#n.part.add("container"),this.#n.addEventListener("keydown",r=>this.#f(r)),t.append(e,this.#n)}connectedCallback(){this.#i+=1;let t=this.#i,e=k(this);if(e.status!=="ok"){this.#p(e.reason);return}let r=pe(e.config);if(r.status!=="ok"){this.#p(r.reason);return}this.#s=r.config,this.#r=N(this);let n=r.config.source;if(n===void 0){this.#t=r.config.cards??[],this.#x(),this.#w();return}this.#g("loading","Loading cards\u2026"),this.#h(n,t)}disconnectedCallback(){this.#i+=1}async#h(t,e){let r=await G(t);if(e!==this.#i)return;if(r.status!=="ok"){this.#p(r.reason);return}let n=Ht(r.data);if(n===null){this.#p(`source "${t}" is not a list of cards`);return}this.#t=n,this.#x(),this.#w()}#x(){if(this.#r===void 0)return;let t=I(this.#r);if(t===void 0)return;let e=this.#t.map(r=>r.id).filter(r=>B(t.selectedCardIds).includes(r));this.#e=this.#s?.mode==="single"?e.slice(0,1):e,this.#o=H(t.comments)}#p(t){this.#c.clear(),this.#a=null,this.#u=null;let e=document.createElement("div");e.part.add("unavailable"),e.setAttribute("role","status");let r=document.createElement("span");r.part.add("kind"),r.textContent="cards";let n=document.createElement("span");n.part.add("reason"),n.textContent=t,e.append("Component unavailable: ",r,n),this.#n.replaceChildren(e)}#g(t,e){let r=document.createElement("div");r.part.add(t),r.setAttribute("role","status"),r.textContent=e,this.#n.replaceChildren(r)}#w(){let t=this.#s;if(t===null)return;this.#c.clear(),this.#a=null,this.#u=null;let e=new Set(this.#t.map(n=>n.id));if(this.#e=this.#e.filter(n=>e.has(n)),this.#o=this.#o.filter(n=>n.anchor.kind!=="card"||e.has(n.anchor.cardId)),this.#t.length===0){this.#g("empty","No cards to choose from.");return}let r=document.createElement("div");r.part.add("grid"),t.columns===3&&(r.dataset.columns="3"),r.append(...this.#t.map(n=>this.#y(n,t.mode,this.#d))),this.#n.replaceChildren(r),this.#v()}#y(t,e,r){let n=document.createElement("div");n.part.add("card"),n.dataset.cardId=t.id;let i=document.createElement("div");i.part.add("card-header");let a=document.createElement("label");a.part.add("card-label");let s=document.createElement("input");s.part.add("control"),s.type=e==="single"?"radio":"checkbox",s.name=r,s.value=t.id,s.addEventListener("change",()=>this.#A(t.id,s.checked)),s.addEventListener("focus",()=>this.#m(t.id,!1));let c=document.createElement("span");c.part.add("card-heading");let d=document.createElement("span");if(d.part.add("card-title"),d.textContent=t.title,c.append(d),t.subtitle!==void 0&&t.subtitle!==""){let m=document.createElement("span");m.part.add("card-subtitle"),m.textContent=t.subtitle,c.append(m)}let u=document.createElement("button");if(u.type="button",u.part.add("comment-button"),u.addEventListener("click",m=>{m.stopPropagation(),this.#m(t.id,!1),this.#T({kind:"card",cardId:t.id},t.title,n,null)}),a.append(s,c),i.append(a,u),n.append(i),t.body!==void 0&&t.body!==""){let m=document.createElement("p");m.part.add("card-body"),m.textContent=t.body,n.append(m)}let g=null;return t.tag!==void 0&&t.tag!==""&&(g=document.createElement("span"),g.part.add("tag"),g.textContent=t.tag,n.append(g)),n.addEventListener("mouseenter",()=>this.#m(t.id,!1)),n.addEventListener("mouseleave",()=>{this.#l===t.id&&this.#m(null,!1)}),n.addEventListener("focusin",()=>this.#m(t.id,!1)),this.#c.set(t.id,{root:n,control:s,commentButton:u,tag:g}),n}#v(){let t=this.#s?.mode??"multi",e=t==="single"?this.#e[0]??this.#t[0]?.id:void 0;for(let r of this.#t){let n=this.#c.get(r.id);if(n===void 0)continue;let i=this.#e.includes(r.id);n.root.part.toggle("selected",i),n.root.part.toggle("active",this.#l===r.id),n.control.checked=i,n.control.tabIndex=t==="single"&&r.id!==e?-1:0;let a=b(this.#o,{kind:"card",cardId:r.id});this.#k(n.commentButton,a,r.title)}}#k(t,e,r){let n=e!==void 0,i=t.part.contains("has-comment")!==n;t.part.toggle("has-comment",n),t.setAttribute("aria-label",n?`Edit comment on ${r}`:`Comment on ${r}`),n?t.title=e.text:t.removeAttribute("title"),(i||t.childElementCount===0)&&t.replaceChildren(he(n))}#m(t,e){this.#l===t&&!e||(this.#l=t,this.#v(),e&&t!==null&&this.#c.get(t)?.control.focus())}#A(t,e){if(this.#s!==null){if(this.#s.mode==="single")this.#e=[t];else{let r=e?[...this.#e,t]:this.#e.filter(n=>n!==t);this.#e=this.#t.map(n=>n.id).filter(n=>r.includes(n))}this.#v(),this.#M()}}#f(t){if(t.metaKey||t.ctrlKey||t.altKey||me(t.target))return;let e=this.#t.map(i=>i.id);if(e.length===0)return;let r=t.key.toLowerCase(),n=this.#l??this.#e[this.#e.length-1]??e[0]??"";if(r==="j"||r==="k"){t.preventDefault();let i=Math.max(0,e.indexOf(n)),s=e[(i+(r==="j"?1:-1)+e.length)%e.length];s!==void 0&&this.#m(s,!0);return}if(r==="x"){t.preventDefault(),this.#A(n,this.#s?.mode==="single"?!0:!this.#e.includes(n));return}if(r==="c"){t.preventDefault();let i=this.#t.find(s=>s.id===n),a=this.#c.get(n);if(i===void 0||a===void 0)return;this.#m(n,!1),this.#T({kind:"card",cardId:i.id},i.title,a.root,null)}}#T(t,e,r,n){if(r===null)return;let i=this.#a?.anchor,a=i!==void 0&&i.kind===t.kind&&(t.kind!=="card"||i.kind==="card"&&i.cardId===t.cardId);this.#b(!1),!a&&this.#E({anchor:t,target:e,mount:r,after:n})}#E(t){let e=document.createElement("div");e.part.add("comment-editor"),e.addEventListener("click",u=>u.stopPropagation());let r=document.createElement("p");r.part.add("comment-subject"),r.textContent=`Comment on ${t.target}`;let n=document.createElement("textarea");n.part.add("comment-input"),n.placeholder="What should the agent know about this?",n.value=b(this.#o,t.anchor)?.text??"";let i=document.createElement("div");i.part.add("comment-actions");let a=document.createElement("span");a.part.add("comment-hint"),a.textContent=b(this.#o,t.anchor)!==void 0?"empty to delete":"\u2318\u21B5 to save";let s=document.createElement("div");s.part.add("comment-buttons");let c=document.createElement("button");c.type="button",c.part.add("comment-cancel"),c.textContent="Cancel",c.addEventListener("click",()=>this.#b(!0));let d=document.createElement("button");d.type="button",d.part.add("comment-save"),d.textContent="Save",d.addEventListener("click",()=>this.#C(n.value)),s.append(c,d),i.append(a,s),n.addEventListener("keydown",u=>{if(u.key==="Enter"&&(u.metaKey||u.ctrlKey)){u.preventDefault(),this.#C(n.value);return}u.key==="Escape"&&(u.preventDefault(),this.#b(!0))}),e.append(r,n,i),t.after!==null?t.after.after(e):t.mount.append(e),this.#a=t,this.#u=e,n.focus()}#b(t){let e=this.#a;this.#u?.remove(),this.#u=null,this.#a=null,!(!t||e===null)&&e.anchor.kind==="card"&&this.#c.get(e.anchor.cardId)?.control.focus()}#C(t){let e=this.#a;e!==null&&(this.#o=R(this.#o,e.anchor,t),this.#b(!0),this.#v(),this.#M())}#I(){return{selectedCardIds:[...this.#e],comments:this.#o.map(t=>({...t}))}}#M(){this.#r!==void 0&&$(this.#r,this.#I())}};v("crtr-cards",ut);var W=["var(--crtr-chart-1)","var(--crtr-chart-2)","var(--crtr-chart-3)","var(--crtr-chart-4)","var(--crtr-chart-5)"],fe="http://www.w3.org/2000/svg",q=260,$t=12,ge=12,be=28,ve=5,It=88,xe=5.8,Nt=14,ye=/^\d{4}-\d{2}-\d{2}(?:[T ]|$)/,Ee=/^\d{4}-\d{2}-\d{2}$/,we=`
|
|
1100
1100
|
:host {
|
|
1101
1101
|
display: block;
|
|
1102
1102
|
}
|
|
@@ -1194,7 +1194,7 @@
|
|
|
1194
1194
|
fill: var(--crtr-color-text-muted);
|
|
1195
1195
|
font-size: calc(var(--crtr-font-size) * 0.72);
|
|
1196
1196
|
}
|
|
1197
|
-
`;function
|
|
1197
|
+
`;function ke(o){let t=o.kind;if(t!=="line"&&t!=="bar"&&t!=="area")return{status:"invalid",reason:"chart kind must be line, bar or area"};let e=o.x;if(typeof e!="string"||e==="")return{status:"invalid",reason:"chart config has no x field"};if(!Array.isArray(o.y)||o.y.length===0)return{status:"invalid",reason:"chart config has no y series"};let r=[];for(let[n,i]of o.y.entries()){if(i===null||typeof i!="object"||Array.isArray(i))return{status:"invalid",reason:`chart series #${n} is not { field, label? }`};let a=i;if(typeof a.field!="string"||a.field==="")return{status:"invalid",reason:`chart series #${n} has no field`};if(a.label!==void 0&&typeof a.label!="string")return{status:"invalid",reason:`chart series "${a.field}" label is not a string`};r.push({field:a.field,label:a.label})}return o.title!==void 0&&typeof o.title!="string"?{status:"invalid",reason:"chart title is not a string"}:o.source!==void 0&&typeof o.source!="string"?{status:"invalid",reason:"chart source is not a string"}:{status:"ok",config:{kind:t,x:e,y:r,title:o.title,data:o.data,source:o.source}}}function Ot(o){return Array.isArray(o)&&o.every(t=>t!==null&&typeof t=="object"&&!Array.isArray(t))}function zt(o,t){return t.split(".").reduce((e,r)=>{if(!(e==null||typeof e!="object"))return e[r]},o)}function pt(o){return o.includes(" ")?o:(o.includes(".")?o.split(".").pop()??o:o).replace(/[_-]+/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").split(/\s+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(" ")}function Ce(o){if(typeof o=="number")return Number.isFinite(o)?o:null;if(typeof o=="boolean")return o?1:0;if(typeof o=="bigint")return Number(o);if(typeof o=="string"){let t=o.replace(/[\s,_]/g,"").replace(/^[$£€¥]/,"").replace(/%$/,"");if(t===""||t==="-")return null;let e=Number(t);return Number.isFinite(e)?e:null}return null}function Te(o){if(o==null)return"";if(o instanceof Date)return Number.isNaN(o.getTime())?"":o.toLocaleDateString(void 0,{month:"short",day:"numeric"});if(typeof o=="string"){let t=o.trim();if(ye.test(t)){let e=new Date(t);if(!Number.isNaN(e.getTime()))return e.toLocaleDateString(void 0,Ee.test(t)?{month:"short",day:"numeric",timeZone:"UTC"}:{month:"short",day:"numeric"})}return o}return typeof o=="object"?"":String(o)}function Ae(o){return o.length>Nt?`${o.slice(0,Nt-1)}\u2026`:o}function Me(o,t,e){let r=t>=1?0:Math.min(4,Math.ceil(-Math.log10(t)));return new Intl.NumberFormat(void 0,{maximumFractionDigits:r,notation:e?"compact":"standard"}).format(o)}function Dt(o){return new Intl.NumberFormat(void 0,{maximumFractionDigits:4}).format(o)}function Se(o,t,e){let r=o,n=t;if((!Number.isFinite(r)||!Number.isFinite(n))&&(r=0,n=1),r===n){let m=Math.abs(r)>0?Math.abs(r)*.1:1;r-=m,n+=m}let i=(n-r)/Math.max(1,e),a=10**Math.floor(Math.log10(i)),s=i/a,c=(s<=1?1:s<=2?2:s<=5?5:10)*a,d=Math.floor(r/c)*c,u=Math.ceil(n/c)*c,g=[];for(let m=d;m<=u+c/2;m+=c)g.push(Number(m.toFixed(10)));return{ticks:g,domainMin:d,domainMax:u,step:c}}function Le(o){let t=[],e=[];for(let r of o){let n=e[e.length-1];if(n===void 0||r.index===n.index+1){e.push(r);continue}t.push(e),e=[r]}return e.length>0&&t.push(e),t}function C(o,t){let e=document.createElementNS(fe,o);return t!==void 0&&e.setAttribute("part",t),e}function O(o,t){for(let[e,r]of Object.entries(t))o.setAttribute(e,String(r))}function jt(o){let t=C("title");return t.textContent=o,t}var mt=class extends HTMLElement{#n=document.createElement("div");#d=document.createElement("div");#s=document.createElement("div");#t=document.createElement("div");#r=null;#e=null;#o=null;#l=0;#c=0;constructor(){super();let t=this.attachShadow({mode:"open"}),e=document.createElement("style");e.textContent=we,this.#n.part.add("container"),this.#d.part.add("title"),this.#s.part.add("legend"),this.#t.part.add("plot"),t.append(e,this.#n)}connectedCallback(){let t=++this.#c;this.#r=null,this.#e=null;let e=k(this);if(e.status!=="ok"){this.#i(e.reason);return}let r=ke(e.config);if(r.status!=="ok"){this.#i(r.reason);return}this.#r=r.config,this.#x(),this.#u();let{data:n,source:i}=r.config;if(n!==void 0){if(!Ot(n)){this.#i("chart data is not a list of rows");return}this.#e=n,this.#p();return}if(i===void 0||i===""){this.#e=[],this.#p();return}this.#h("Loading chart data\u2026"),this.#a(i,t)}disconnectedCallback(){this.#c+=1,this.#o?.disconnect(),this.#o=null}async#a(t,e){let r=await G(t);if(e===this.#c){if(r.status!=="ok"){this.#i(`chart source "${t}" is ${r.status}: ${r.reason}`);return}if(!Ot(r.data)){this.#i(`chart source "${t}" is not a list of rows`);return}this.#e=r.data,this.#p()}}#u(){this.#o?.disconnect(),this.#l=this.#t.getBoundingClientRect().width;let t=new ResizeObserver(e=>{let r=e[0]?.contentRect.width??0;Math.abs(this.#l-r)<.5||(this.#l=r,this.#p())});t.observe(this.#t),this.#o=t}#i(t){this.#o?.disconnect(),this.#o=null;let e=document.createElement("div");e.part.add("unavailable"),e.setAttribute("role","status");let r=document.createElement("span");r.part.add("reason"),r.textContent=t,e.append("Chart unavailable: ",r),this.#n.replaceChildren(e)}#h(t){let e=document.createElement("div");e.part.add("status"),e.setAttribute("role","status"),e.style.height=`${q}px`,e.textContent=t,this.#t.replaceChildren(e)}#x(){let t=this.#r;if(t===null)return;let e=[],r=t.title?.trim();r!==void 0&&r.length>0&&(this.#d.textContent=r,e.push(this.#d)),t.y.length>1&&(this.#s.replaceChildren(...t.y.map((n,i)=>{let a=document.createElement("div");a.part.add("legend-item");let s=document.createElement("span");s.part.add("legend-swatch"),s.setAttribute("aria-hidden","true"),s.style.background=W[i%W.length]??W[0];let c=document.createElement("span");return c.part.add("legend-label"),c.textContent=n.label??pt(n.field),a.append(s,c),a})),e.push(this.#s)),e.push(this.#t),this.#n.replaceChildren(...e)}#p(){let t=this.#r,e=this.#e;if(t===null||e===null)return;let r=e.map(l=>Te(zt(l,t.x))),n=t.y.map((l,p)=>{let h=[];return e.forEach((f,x)=>{let E=Ce(zt(f,l.field));E!==null&&h.push({index:x,value:E})}),{label:l.label??pt(l.field),color:W[p%W.length]??W[0],points:h}}),i=0,a=0,s=0;for(let l of n)for(let p of l.points)i===0?(a=p.value,s=p.value):(p.value<a&&(a=p.value),p.value>s&&(s=p.value)),i+=1;if(t.kind!=="line"&&(a=Math.min(a,0),s=Math.max(s,0)),i===0||e.length===0){let l=document.createElement("div");l.part.add("empty"),l.style.height=`${q}px`,l.textContent="No data to chart",this.#t.replaceChildren(l);return}let c=this.#l;if(c<=0){let l=document.createElement("div");l.style.height=`${q}px`,this.#t.replaceChildren(l);return}let{ticks:d,domainMin:u,domainMax:g,step:m}=Se(a,s,ve),V=Math.max(...d.map(l=>Math.abs(l)))>=1e4,P=d.map(l=>Me(l,m,V)),A=Math.min(88,Math.max(36,Math.max(...P.map(l=>l.length))*6.4+12)),T=Math.max(0,c-A-ge),M=Math.max(0,q-$t-be),y=$t+M,rt=r.length>0?T/r.length:T,_=l=>A+rt*(l+.5),_t=g-u||1,z=l=>y-(l-u)/_t*M,bt=Math.min(Math.max(0,u),g),X=z(bt),D=C("svg","chart");O(D,{role:"img",width:c,height:q,viewBox:`0 0 ${c} ${q}`}),D.setAttribute("aria-label",`${t.kind} chart of ${n.map(l=>l.label).join(", ")} by ${pt(t.x)}`),d.forEach((l,p)=>{let h=C("line");h.setAttribute("class","grid"),O(h,{x1:A,x2:A+T,y1:z(l),y2:z(l),opacity:l===bt?.9:.45});let f=C("text");f.setAttribute("class","tick"),O(f,{x:A-8,y:z(l),"text-anchor":"end","dominant-baseline":"central"}),f.textContent=P[p]??"",D.append(h,f)});let j=[];if(r.length>0){let l=Math.max(2,Math.min(r.length,Math.floor(T/It)||1)),p=Math.max(1,Math.ceil((r.length-1)/(l-1)));for(let f=0;f<r.length;f+=p)j.push(f);let h=j[j.length-1]??0;h!==r.length-1&&((r.length-1-h)*rt>=It?j.push(r.length-1):j[j.length-1]=r.length-1)}for(let l of j){let p=Ae(r[l]??""),h=_(l),f=p.length*xe/2,x=h-f<0?"start":h+f>c?"end":"middle",E=C("text");E.setAttribute("class","tick"),O(E,{x:x==="start"?0:x==="end"?c:h,y:y+16,"text-anchor":x,"dominant-baseline":"hanging"}),E.textContent=p,D.append(E)}if(t.kind==="bar"){let l=rt*.72,p=l/n.length,h=Math.max(1,p-(p>4?1:0));n.forEach((f,x)=>{let E=C("g");for(let S of f.points){let U=z(S.value),L=C("rect","bar");O(L,{x:_(S.index)-l/2+x*p,y:Math.min(U,X),width:h,height:Math.max(1,Math.abs(X-U)),rx:Math.min(2,h/3)}),L.style.fill=f.color,L.append(jt(`${f.label} \xB7 ${r[S.index]??S.index}: ${Dt(S.value)}`)),E.append(L)}D.append(E)})}else{let l=r.length<=40;for(let p of n){let h=C("g"),f=Le(p.points);for(let x of f){let E=x.map(w=>`${_(w.index)},${z(w.value)}`).join(" L "),S=x[0],U=x[x.length-1];if(t.kind==="area"&&S!==void 0&&U!==void 0){let w=C("path","area");O(w,{d:`M ${_(S.index)},${X} L ${E} L ${_(U.index)},${X} Z`,"fill-opacity":.18}),w.style.fill=p.color,h.append(w)}let L=C("path","line");if(O(L,{d:`M ${E}`,fill:"none","stroke-width":2,"stroke-linecap":"round","stroke-linejoin":"round"}),L.style.stroke=p.color,h.append(L),!(!l&&x.length>1))for(let w of x){let J=C("circle","point");O(J,{cx:_(w.index),cy:z(w.value),r:2.5}),J.style.fill=p.color,J.append(jt(`${p.label} \xB7 ${r[w.index]??w.index}: ${Dt(w.value)}`)),h.append(J)}}D.append(h)}}this.#t.replaceChildren(D)}};v("crtr-chart",mt);function Bt(){return window.crtr}var Pt="Submit is unavailable \u2014 this page is not connected to a host.",Re=`
|
|
1198
1198
|
:host {
|
|
1199
1199
|
display: block;
|
|
1200
1200
|
}
|
|
@@ -1211,7 +1211,7 @@
|
|
|
1211
1211
|
[part="page"]:focus {
|
|
1212
1212
|
outline: none;
|
|
1213
1213
|
}
|
|
1214
|
-
`,
|
|
1214
|
+
`,He=`
|
|
1215
1215
|
:host {
|
|
1216
1216
|
display: block;
|
|
1217
1217
|
}
|
|
@@ -1316,7 +1316,7 @@
|
|
|
1316
1316
|
[hidden] {
|
|
1317
1317
|
display: none !important;
|
|
1318
1318
|
}
|
|
1319
|
-
`,
|
|
1319
|
+
`,ht=class extends HTMLElement{constructor(){super();let t=this.attachShadow({mode:"open"}),e=document.createElement("style");e.textContent=Re;let r=document.createElement("div");r.part.add("page"),r.append(document.createElement("slot")),t.append(e,r)}},ft=class extends HTMLElement{static observedAttributes=["disabled","submit-label"];#n=[];#d=0;#s="idle";#t=null;#r=document.createElement("div");#e=document.createElement("div");#o=document.createElement("div");#l=document.createElement("span");#c=document.createElement("span");#a=document.createElement("div");#u=document.createElement("span");#i=document.createElement("button");#h=document.createElement("button");#x=document.createElement("button");#p=new MutationObserver(()=>{this.#g(),this.#m()});constructor(){super();let t=this.attachShadow({mode:"open"}),e=document.createElement("style");e.textContent=He;let r=document.createElement("div");r.part.add("steps"),r.append(document.createElement("slot")),this.#r.part.add("container"),this.#e.part.add("chrome"),this.#o.part.add("progress"),this.#o.setAttribute("role","status"),this.#o.setAttribute("aria-live","polite"),this.#l.part.add("progress-label"),this.#c.part.add("progress-track"),this.#c.setAttribute("aria-hidden","true"),this.#o.append(this.#l,this.#c),this.#i.part.add("prev"),this.#i.type="button",this.#i.textContent="Back",this.#i.addEventListener("click",()=>this.#y(-1)),this.#h.part.add("next"),this.#h.type="button",this.#h.textContent="Next",this.#h.addEventListener("click",()=>this.#y(1)),this.#x.part.add("submit"),this.#x.type="button",this.#x.addEventListener("click",()=>{this.#v()}),this.#u.part.add("notice"),this.#a.part.add("actions"),this.#a.append(this.#u,this.#i,this.#h,this.#x),this.#e.append(this.#o,this.#a),this.#r.append(r,this.#e),t.append(e,this.#r)}connectedCallback(){this.#g(),this.#p.observe(this,{childList:!0}),this.ownerDocument.addEventListener("keydown",this.#k),this.#m()}disconnectedCallback(){this.#p.disconnect(),this.ownerDocument.removeEventListener("keydown",this.#k)}attributeChangedCallback(){this.isConnected&&this.#m()}#g(){this.#n=[...this.children].filter(t=>t instanceof HTMLElement&&t.tagName==="CRTR-PAGE");for(let t of this.#n)t.hasAttribute("tabindex")||t.setAttribute("tabindex","-1");this.#d=Math.min(this.#d,Math.max(0,this.#n.length-1))}get#w(){return this.#d>=this.#n.length-1}#y(t,e=!0){let r=this.#d+t;r<0||r>=this.#n.length||r===this.#d||(this.#d=r,this.#t=null,this.#m(),e&&this.#n[this.#d]?.focus())}async#v(){if(this.#s!=="idle"||this.hasAttribute("disabled")||!this.#w)return;let t=Bt();if(typeof t?.submit!="function"){this.#t=Pt,this.#m();return}this.#s="submitting",this.#t=null,this.#m();try{await t.submit(),this.#s="submitted"}catch(e){this.#s="idle",this.#t=e instanceof Error?e.message:"Submit failed."}this.#m()}#k=t=>{if(t.defaultPrevented)return;let e=t.composedPath();if(e.some(n=>n instanceof HTMLElement&&n.tagName==="CRTR-PAGES"&&n!==this))return;if((t.metaKey||t.ctrlKey)&&t.key==="Enter"){if(!this.#w)return;t.preventDefault(),this.#v();return}if(t.metaKey||t.ctrlKey||t.altKey||$e(e))return;let r=t.key.toLowerCase();r!=="n"&&r!=="p"||(t.preventDefault(),this.#y(r==="n"?1:-1))};#m(){let t=this.#n.length,e=t>1,r=Math.min(this.#d,Math.max(0,t-1));for(let[a,s]of this.#n.entries())s.toggleAttribute("hidden",a!==r);if(this.#r.dataset.steps=String(Math.max(1,t)),this.#r.dataset.step=String(r+1),this.#o.hidden=!e,e){let a=this.#n[r]?.getAttribute("label")?.trim();this.#l.textContent=a?`Step ${r+1} of ${t} \xB7 ${a}`:`Step ${r+1} of ${t}`,this.#c.replaceChildren(...this.#n.map((s,c)=>{let d=document.createElement("span");return d.part.add("progress-step"),d.dataset.state=c===r?"current":c<r?"complete":"upcoming",d}))}this.#i.hidden=!e,this.#i.disabled=r===0,this.#h.hidden=!e||this.#w,this.#h.disabled=!1,this.#x.hidden=!this.#w;let n=typeof Bt()?.submit=="function";this.#x.disabled=!n||this.#s!=="idle"||this.hasAttribute("disabled"),this.#x.textContent=this.#s==="submitting"?"Submitting\u2026":this.#s==="submitted"?"Submitted":this.getAttribute("submit-label")?.trim()||"Submit";let i=this.#t??(this.#s==="submitted"?"Your response was submitted.":!n&&this.#w?Pt:null);this.#u.hidden=i===null,this.#u.textContent=i??"",this.#u.dataset.state=this.#t===null?"info":"error"}};function $e(o){return o.some(t=>t instanceof HTMLElement&&(t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement||t.isContentEditable))}v("crtr-page",ht);v("crtr-pages",ft);var Ie=`
|
|
1320
1320
|
:host {
|
|
1321
1321
|
display: block;
|
|
1322
1322
|
}
|
|
@@ -1344,4 +1344,4 @@
|
|
|
1344
1344
|
margin-top: var(--crtr-space-1);
|
|
1345
1345
|
font-size: 0.9em;
|
|
1346
1346
|
}
|
|
1347
|
-
`,
|
|
1347
|
+
`,gt=class extends HTMLElement{#n=document.createElement("div");#d=document.createElement("span");#s=document.createElement("span");#t=document.createElement("div");#r=!1;constructor(){super();let t=this.attachShadow({mode:"open"}),e=document.createElement("style");e.textContent=Ie,this.#n.part.add("unavailable"),this.#n.setAttribute("role","status"),this.#d.part.add("kind"),this.#s.part.add("reason"),this.#n.append("Component unavailable: ",this.#d,this.#s),this.#n.hidden=!0,this.#t.part.add("mount"),t.append(e,document.createElement("slot"),this.#n)}connectedCallback(){if(this.#r)return;this.#r=!0;let t=this.getAttribute("kind")?.trim()??"";if(this.#d.textContent=t===""?"unknown":t,t===""){this.#o("This slot names no component kind.");return}let e=k(this);if(e.status!=="ok"){this.#o(e.reason);return}this.append(this.#t),this.#e(t,e.config)}async#e(t,e){await yt(this.#t,t,e)!=="mounted"&&(this.#t.remove(),this.#o("This page is open somewhere that cannot render it."))}#o(t){this.#s.textContent=t,this.#n.hidden=!1}};v("crtr-slot",gt);})();
|
package/dist/pages/comments.d.ts
CHANGED
|
@@ -23,6 +23,15 @@ export declare function findComment(comments: Comment[], anchor: CommentAnchor):
|
|
|
23
23
|
* response is stable across retyping.
|
|
24
24
|
*/
|
|
25
25
|
export declare function setComment(comments: Comment[], anchor: CommentAnchor, text: string): Comment[];
|
|
26
|
+
/**
|
|
27
|
+
* Take over a comment list the host saved earlier (`savedResponse`), as this element's own
|
|
28
|
+
* local state. Malformed entries are dropped rather than thrown on — hydration must never be
|
|
29
|
+
* the reason a page fails to render — and the one-comment-per-anchor rule is re-imposed.
|
|
30
|
+
*
|
|
31
|
+
* Adopting also advances the id counter past every `cN` id taken from the saved list, so a
|
|
32
|
+
* comment written after a reopen cannot be minted with an id a saved comment already holds.
|
|
33
|
+
*/
|
|
34
|
+
export declare function adoptComments(value: unknown): Comment[];
|
|
26
35
|
/**
|
|
27
36
|
* Comment ids are frame-local: the host does not mint them, and nothing downstream keys off
|
|
28
37
|
* their value — `validatePageResponses` only requires a non-empty string. One counter is
|
package/dist/pages/comments.js
CHANGED
|
@@ -49,6 +49,59 @@ export function setComment(comments, anchor, text) {
|
|
|
49
49
|
return [...rest, { id: existing?.id ?? newCommentId(), anchor, text: trimmed }];
|
|
50
50
|
}
|
|
51
51
|
let counter = 0;
|
|
52
|
+
/** Whether a value read back from a host is a comment anchor this bundle understands. */
|
|
53
|
+
function isAnchor(value) {
|
|
54
|
+
if (typeof value !== 'object' || value === null)
|
|
55
|
+
return false;
|
|
56
|
+
const anchor = value;
|
|
57
|
+
switch (anchor.kind) {
|
|
58
|
+
case 'whole':
|
|
59
|
+
return true;
|
|
60
|
+
case 'option':
|
|
61
|
+
return typeof anchor.optionId === 'string';
|
|
62
|
+
case 'row':
|
|
63
|
+
return typeof anchor.rowId === 'string';
|
|
64
|
+
case 'column':
|
|
65
|
+
return typeof anchor.columnId === 'string';
|
|
66
|
+
case 'card':
|
|
67
|
+
return typeof anchor.cardId === 'string';
|
|
68
|
+
case 'range':
|
|
69
|
+
return typeof anchor.start === 'number' && typeof anchor.end === 'number' && typeof anchor.quote === 'string';
|
|
70
|
+
default:
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Take over a comment list the host saved earlier (`savedResponse`), as this element's own
|
|
76
|
+
* local state. Malformed entries are dropped rather than thrown on — hydration must never be
|
|
77
|
+
* the reason a page fails to render — and the one-comment-per-anchor rule is re-imposed.
|
|
78
|
+
*
|
|
79
|
+
* Adopting also advances the id counter past every `cN` id taken from the saved list, so a
|
|
80
|
+
* comment written after a reopen cannot be minted with an id a saved comment already holds.
|
|
81
|
+
*/
|
|
82
|
+
export function adoptComments(value) {
|
|
83
|
+
if (!Array.isArray(value))
|
|
84
|
+
return [];
|
|
85
|
+
const adopted = [];
|
|
86
|
+
for (const entry of value) {
|
|
87
|
+
if (typeof entry !== 'object' || entry === null)
|
|
88
|
+
continue;
|
|
89
|
+
const { id, anchor, text } = entry;
|
|
90
|
+
if (typeof id !== 'string' || id === '')
|
|
91
|
+
continue;
|
|
92
|
+
if (typeof text !== 'string' || text.trim() === '')
|
|
93
|
+
continue;
|
|
94
|
+
if (!isAnchor(anchor))
|
|
95
|
+
continue;
|
|
96
|
+
if (findComment(adopted, anchor) !== undefined)
|
|
97
|
+
continue;
|
|
98
|
+
adopted.push({ id, anchor: { ...anchor }, text });
|
|
99
|
+
const minted = /^c(\d+)$/.exec(id);
|
|
100
|
+
if (minted !== null)
|
|
101
|
+
counter = Math.max(counter, Number(minted[1]));
|
|
102
|
+
}
|
|
103
|
+
return adopted;
|
|
104
|
+
}
|
|
52
105
|
/**
|
|
53
106
|
* Comment ids are frame-local: the host does not mint them, and nothing downstream keys off
|
|
54
107
|
* their value — `validatePageResponses` only requires a non-empty string. One counter is
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
* a malformed config, an unreachable source, source data that is not a card list — becomes
|
|
15
15
|
* a named unavailable state rather than an exception.
|
|
16
16
|
*/
|
|
17
|
-
import { findComment, setComment } from '../comments.js';
|
|
18
|
-
import { artifactData, respond } from '../host.js';
|
|
17
|
+
import { adoptComments, findComment, setComment } from '../comments.js';
|
|
18
|
+
import { artifactData, respond, savedIds, savedResponse } from '../host.js';
|
|
19
19
|
import { registerElement } from '../register.js';
|
|
20
20
|
import { readSlotConfig, readSlotId } from '../slot-config.js';
|
|
21
21
|
const STYLE = `
|
|
@@ -455,6 +455,7 @@ class CrtrCardsElement extends HTMLElement {
|
|
|
455
455
|
const source = normalized.config.source;
|
|
456
456
|
if (source === undefined) {
|
|
457
457
|
this.#cards = normalized.config.cards ?? [];
|
|
458
|
+
this.#hydrate();
|
|
458
459
|
this.#build();
|
|
459
460
|
return;
|
|
460
461
|
}
|
|
@@ -479,8 +480,24 @@ class CrtrCardsElement extends HTMLElement {
|
|
|
479
480
|
return;
|
|
480
481
|
}
|
|
481
482
|
this.#cards = cards;
|
|
483
|
+
this.#hydrate();
|
|
482
484
|
this.#build();
|
|
483
485
|
}
|
|
486
|
+
/**
|
|
487
|
+
* Seed local state from the answer the host is already holding, so a reopened page shows
|
|
488
|
+
* the cards that were picked. `#build` is what drops ids the current data no longer has,
|
|
489
|
+
* so this only has to re-impose single-select.
|
|
490
|
+
*/
|
|
491
|
+
#hydrate() {
|
|
492
|
+
if (this.#slotId === undefined)
|
|
493
|
+
return;
|
|
494
|
+
const saved = savedResponse(this.#slotId);
|
|
495
|
+
if (saved === undefined)
|
|
496
|
+
return;
|
|
497
|
+
const ids = this.#cards.map((card) => card.id).filter((id) => savedIds(saved.selectedCardIds).includes(id));
|
|
498
|
+
this.#selected = this.#config?.mode === 'single' ? ids.slice(0, 1) : ids;
|
|
499
|
+
this.#comments = adoptComments(saved.comments);
|
|
500
|
+
}
|
|
484
501
|
// ---------------------------------------------------------------- rendering
|
|
485
502
|
#renderUnavailable(reason) {
|
|
486
503
|
this.#nodes.clear();
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
* the way the question did. `freetext` is absent rather than empty: the response says whether
|
|
19
19
|
* the user wrote something, not whether the box existed.
|
|
20
20
|
*/
|
|
21
|
-
import { setComment, findComment } from '../comments.js';
|
|
22
|
-
import { respond } from '../host.js';
|
|
21
|
+
import { adoptComments, setComment, findComment } from '../comments.js';
|
|
22
|
+
import { respond, savedIds, savedResponse } from '../host.js';
|
|
23
23
|
import { registerElement } from '../register.js';
|
|
24
24
|
import { readSlotConfig, readSlotId } from '../slot-config.js';
|
|
25
25
|
const BUBBLE_PLUS = '<svg viewBox="0 0 16 16" aria-hidden="true" focusable="false"><path d="M2.5 3.5h11v7h-6l-3 2.5v-2.5h-2z"/><path d="M8 5.5v3M6.5 7h3"/></svg>';
|
|
@@ -316,12 +316,34 @@ class CrtrOptionsElement extends HTMLElement {
|
|
|
316
316
|
}
|
|
317
317
|
this.#config = config;
|
|
318
318
|
this.#order = config.options.map((option) => option.id);
|
|
319
|
+
this.#hydrate(config);
|
|
319
320
|
this.#render(config);
|
|
320
321
|
this.#sync();
|
|
321
322
|
}
|
|
322
323
|
disconnectedCallback() {
|
|
323
324
|
document.removeEventListener('pointerdown', this.#onDocumentPointerDown, true);
|
|
324
325
|
}
|
|
326
|
+
/**
|
|
327
|
+
* Seed local state from the answer the host is already holding, so a reopened page shows
|
|
328
|
+
* what it would submit. Ids that no longer name an option are dropped, and single-select
|
|
329
|
+
* keeps only the first, so a stale saved answer cannot put the control in a state the user
|
|
330
|
+
* could not have clicked into.
|
|
331
|
+
*/
|
|
332
|
+
#hydrate(config) {
|
|
333
|
+
if (this.#slotId === undefined)
|
|
334
|
+
return;
|
|
335
|
+
const saved = savedResponse(this.#slotId);
|
|
336
|
+
if (saved === undefined)
|
|
337
|
+
return;
|
|
338
|
+
const selected = savedIds(saved.selectedOptionIds);
|
|
339
|
+
this.#selected = this.#order.filter((id) => selected.includes(id));
|
|
340
|
+
if (config.mode === 'single')
|
|
341
|
+
this.#selected = this.#selected.slice(0, 1);
|
|
342
|
+
this.#comments = adoptComments(saved.comments).filter((comment) => comment.anchor.kind !== 'option' || this.#order.includes(comment.anchor.optionId));
|
|
343
|
+
if (config.allowFreetext === true && typeof saved.freetext === 'string' && saved.freetext !== '') {
|
|
344
|
+
this.#freetext = saved.freetext;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
325
347
|
/** The named state for a config this element cannot render — never a thrown error. */
|
|
326
348
|
#renderUnavailable(reason) {
|
|
327
349
|
const style = document.createElement('style');
|
|
@@ -447,6 +469,9 @@ class CrtrOptionsElement extends HTMLElement {
|
|
|
447
469
|
const input = document.createElement('textarea');
|
|
448
470
|
input.part.add('freetext-input');
|
|
449
471
|
input.placeholder = config.freetextPlaceholder ?? 'Answer in your own words…';
|
|
472
|
+
// Hydration runs before the render, so the saved words are already in local state.
|
|
473
|
+
if (this.#freetext !== undefined)
|
|
474
|
+
input.value = this.#freetext;
|
|
450
475
|
input.addEventListener('input', () => {
|
|
451
476
|
// Absent rather than empty — see the note on `freetext` in the response type.
|
|
452
477
|
this.#freetext = input.value === '' ? undefined : input.value;
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
*/
|
|
19
19
|
import { registerElement } from '../register.js';
|
|
20
20
|
import { readSlotConfig, readSlotId } from '../slot-config.js';
|
|
21
|
-
import { artifactData, respond } from '../host.js';
|
|
22
|
-
import { anchorLabel, findComment, setComment } from '../comments.js';
|
|
21
|
+
import { artifactData, respond, savedIds, savedResponse } from '../host.js';
|
|
22
|
+
import { adoptComments, anchorLabel, findComment, setComment } from '../comments.js';
|
|
23
23
|
const COMMENT_BUBBLE = 'M3.25 3.5h9.5A1.75 1.75 0 0 1 14.5 5.25v5A1.75 1.75 0 0 1 12.75 12H7.4l-3.15 2.36A.5.5 0 0 1 3.5 14v-2H3.25A1.75 1.75 0 0 1 1.5 10.25v-5A1.75 1.75 0 0 1 3.25 3.5Z';
|
|
24
24
|
const STYLE = `
|
|
25
25
|
:host {
|
|
@@ -421,6 +421,7 @@ class CrtrTableElement extends HTMLElement {
|
|
|
421
421
|
return;
|
|
422
422
|
}
|
|
423
423
|
this.#rows = config.rows;
|
|
424
|
+
this.#hydrate();
|
|
424
425
|
this.#renderTable();
|
|
425
426
|
}
|
|
426
427
|
disconnectedCallback() {
|
|
@@ -440,8 +441,36 @@ class CrtrTableElement extends HTMLElement {
|
|
|
440
441
|
return;
|
|
441
442
|
}
|
|
442
443
|
this.#rows = rows.rows;
|
|
444
|
+
this.#hydrate();
|
|
443
445
|
this.#renderTable();
|
|
444
446
|
}
|
|
447
|
+
/**
|
|
448
|
+
* Seed local state from the answer the host is already holding, so a reopened page shows
|
|
449
|
+
* the rows and columns that were picked. It runs once the rows are known — after a `source`
|
|
450
|
+
* load, not before — because a saved id is only honoured while it still names something on
|
|
451
|
+
* screen. The select modes are re-imposed for the same reason.
|
|
452
|
+
*/
|
|
453
|
+
#hydrate() {
|
|
454
|
+
if (this.#slotId === undefined)
|
|
455
|
+
return;
|
|
456
|
+
const saved = savedResponse(this.#slotId);
|
|
457
|
+
if (saved === undefined)
|
|
458
|
+
return;
|
|
459
|
+
const rows = this.#orderRows(savedIds(saved.selectedRowIds));
|
|
460
|
+
const columns = this.#orderColumns(savedIds(saved.selectedColumnIds));
|
|
461
|
+
this.#selectedRowIds = this.#rowSelect === 'none' ? [] : this.#rowSelect === 'single' ? rows.slice(0, 1) : rows;
|
|
462
|
+
this.#selectedColumnIds =
|
|
463
|
+
this.#columnSelect === 'none' ? [] : this.#columnSelect === 'single' ? columns.slice(0, 1) : columns;
|
|
464
|
+
const rowIds = new Set(this.#rows.map((row) => row.id));
|
|
465
|
+
const columnIds = new Set((this.#config?.columns ?? []).map((column) => column.id));
|
|
466
|
+
this.#comments = adoptComments(saved.comments).filter((comment) => {
|
|
467
|
+
if (comment.anchor.kind === 'row')
|
|
468
|
+
return rowIds.has(comment.anchor.rowId);
|
|
469
|
+
if (comment.anchor.kind === 'column')
|
|
470
|
+
return columnIds.has(comment.anchor.columnId);
|
|
471
|
+
return true;
|
|
472
|
+
});
|
|
473
|
+
}
|
|
445
474
|
// ── the response ───────────────────────────────────────────────────────────────────────
|
|
446
475
|
get #rowSelect() {
|
|
447
476
|
return this.#config?.rowSelect ?? 'none';
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
*/
|
|
25
25
|
import { registerElement } from '../register.js';
|
|
26
26
|
import { readSlotConfig, readSlotId } from '../slot-config.js';
|
|
27
|
-
import { respond } from '../host.js';
|
|
28
|
-
import { findComment, setComment } from '../comments.js';
|
|
27
|
+
import { respond, savedResponse } from '../host.js';
|
|
28
|
+
import { adoptComments, findComment, setComment } from '../comments.js';
|
|
29
29
|
const WHOLE = { kind: 'whole' };
|
|
30
30
|
const WHOLE_TARGET = 'the whole passage';
|
|
31
31
|
const RANGE_TARGET = 'the selected text';
|
|
@@ -622,6 +622,7 @@ class CrtrTextElement extends HTMLElement {
|
|
|
622
622
|
this.#config = read.config;
|
|
623
623
|
this.#slotId = readSlotId(this);
|
|
624
624
|
this.#text = read.config.initialText;
|
|
625
|
+
this.#hydrate();
|
|
625
626
|
this.#editing = read.config.editable === true && this.#text.length === 0;
|
|
626
627
|
this.#renderToolbar();
|
|
627
628
|
this.#renderSurface();
|
|
@@ -630,6 +631,22 @@ class CrtrTextElement extends HTMLElement {
|
|
|
630
631
|
disconnectedCallback() {
|
|
631
632
|
document.removeEventListener('pointerdown', this.#onDocumentPointerDown, true);
|
|
632
633
|
}
|
|
634
|
+
/**
|
|
635
|
+
* Seed local state from the answer the host is already holding, so a reopened page shows
|
|
636
|
+
* the edited words and the comments on them rather than the agent's original text. An
|
|
637
|
+
* uneditable slot keeps its authored text — only comments carry over — because a saved
|
|
638
|
+
* edit there could not have come from this control.
|
|
639
|
+
*/
|
|
640
|
+
#hydrate() {
|
|
641
|
+
if (this.#slotId === undefined)
|
|
642
|
+
return;
|
|
643
|
+
const saved = savedResponse(this.#slotId);
|
|
644
|
+
if (saved === undefined)
|
|
645
|
+
return;
|
|
646
|
+
if (this.#config.editable === true && typeof saved.text === 'string')
|
|
647
|
+
this.#text = saved.text;
|
|
648
|
+
this.#comments = adoptComments(saved.comments);
|
|
649
|
+
}
|
|
633
650
|
/** The complete current response — what every change hands `respond()`. */
|
|
634
651
|
#response() {
|
|
635
652
|
return { text: this.#text, edited: this.#text !== this.#config.initialText, comments: this.#comments };
|
package/dist/pages/host.d.ts
CHANGED
|
@@ -16,6 +16,12 @@
|
|
|
16
16
|
* the host autosave the partial map; it does not resolve the ticket. Only the pager's
|
|
17
17
|
* submit affordance calls `submit()`, which posts the complete map once.
|
|
18
18
|
*
|
|
19
|
+
* `respond()` has one counterpart, `savedResponse()`: the host hands back the response it is
|
|
20
|
+
* currently holding for a slot, so a page reopened after a partial answer re-mounts SHOWING
|
|
21
|
+
* that answer instead of blank. Every response-bearing element reads it at mount and seeds
|
|
22
|
+
* its visible state from it — that is what keeps "what submit sends" and "what the screen
|
|
23
|
+
* shows" the same thing.
|
|
24
|
+
*
|
|
19
25
|
* The host is optional at the type level (`window.crtr?`) because a page can be opened
|
|
20
26
|
* bare — dropped in a browser, or rendered by a host that installs nothing. Elements read
|
|
21
27
|
* the bridge through the accessors below rather than touching `window.crtr` directly, so
|
|
@@ -42,6 +48,12 @@ export interface CrtrHost {
|
|
|
42
48
|
* partial map. Called on every user change. NOT ticket resolution.
|
|
43
49
|
*/
|
|
44
50
|
respond(slotId: string, response: SlotResponse): void;
|
|
51
|
+
/**
|
|
52
|
+
* The response the host currently holds for this slot — an autosaved partial answer on a
|
|
53
|
+
* reopened page, or the published answer on a resolved one. `undefined` when the host has
|
|
54
|
+
* nothing for the slot. Elements read it at mount; it is the inbound half of `respond`.
|
|
55
|
+
*/
|
|
56
|
+
savedResponse(slotId: string): SlotResponse | undefined;
|
|
45
57
|
/** Posts the complete response map once. Only the pager's submit affordance calls it. */
|
|
46
58
|
submit(): Promise<void>;
|
|
47
59
|
/** Flushes the pending autosave of the partial map. */
|
|
@@ -98,6 +110,20 @@ export declare function host(): CrtrHost | undefined;
|
|
|
98
110
|
* so an unavailable host only means the answer is not being persisted.
|
|
99
111
|
*/
|
|
100
112
|
export declare function respond(slotId: string, response: SlotResponse): HostCall;
|
|
113
|
+
/**
|
|
114
|
+
* The response the host already holds for this slot, or `undefined` when it holds none — a
|
|
115
|
+
* bare page, a first open, or a host without the channel. Elements call this once at mount
|
|
116
|
+
* and seed their visible state from it, so a reopened page shows the answers the host would
|
|
117
|
+
* submit rather than an empty form beside a full response map.
|
|
118
|
+
*
|
|
119
|
+
* `T` is asserted, not verified, exactly like `readSlotConfig`'s config: the host's saved map
|
|
120
|
+
* was validated against this slot's kind before it was stored. What is not guaranteed is that
|
|
121
|
+
* a host implements the channel at all, which is what the `undefined` covers — so seed with
|
|
122
|
+
* the same defensiveness you would give any outside value (`savedIds`, `adoptComments`).
|
|
123
|
+
*/
|
|
124
|
+
export declare function savedResponse<T extends SlotResponse = SlotResponse>(slotId: string): T | undefined;
|
|
125
|
+
/** The string ids of a saved selection field, with anything else in it dropped. */
|
|
126
|
+
export declare function savedIds(value: unknown): string[];
|
|
101
127
|
/**
|
|
102
128
|
* Posts the complete response map once, resolving the ticket. Only the pager's submit
|
|
103
129
|
* affordance calls this.
|
package/dist/pages/host.js
CHANGED
|
@@ -16,6 +16,12 @@
|
|
|
16
16
|
* the host autosave the partial map; it does not resolve the ticket. Only the pager's
|
|
17
17
|
* submit affordance calls `submit()`, which posts the complete map once.
|
|
18
18
|
*
|
|
19
|
+
* `respond()` has one counterpart, `savedResponse()`: the host hands back the response it is
|
|
20
|
+
* currently holding for a slot, so a page reopened after a partial answer re-mounts SHOWING
|
|
21
|
+
* that answer instead of blank. Every response-bearing element reads it at mount and seeds
|
|
22
|
+
* its visible state from it — that is what keeps "what submit sends" and "what the screen
|
|
23
|
+
* shows" the same thing.
|
|
24
|
+
*
|
|
19
25
|
* The host is optional at the type level (`window.crtr?`) because a page can be opened
|
|
20
26
|
* bare — dropped in a browser, or rendered by a host that installs nothing. Elements read
|
|
21
27
|
* the bridge through the accessors below rather than touching `window.crtr` directly, so
|
|
@@ -52,6 +58,33 @@ export function respond(slotId, response) {
|
|
|
52
58
|
return { status: 'failed', reason: reasonOf(error) };
|
|
53
59
|
}
|
|
54
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* The response the host already holds for this slot, or `undefined` when it holds none — a
|
|
63
|
+
* bare page, a first open, or a host without the channel. Elements call this once at mount
|
|
64
|
+
* and seed their visible state from it, so a reopened page shows the answers the host would
|
|
65
|
+
* submit rather than an empty form beside a full response map.
|
|
66
|
+
*
|
|
67
|
+
* `T` is asserted, not verified, exactly like `readSlotConfig`'s config: the host's saved map
|
|
68
|
+
* was validated against this slot's kind before it was stored. What is not guaranteed is that
|
|
69
|
+
* a host implements the channel at all, which is what the `undefined` covers — so seed with
|
|
70
|
+
* the same defensiveness you would give any outside value (`savedIds`, `adoptComments`).
|
|
71
|
+
*/
|
|
72
|
+
export function savedResponse(slotId) {
|
|
73
|
+
const bridge = host();
|
|
74
|
+
if (typeof bridge?.savedResponse !== 'function')
|
|
75
|
+
return undefined;
|
|
76
|
+
try {
|
|
77
|
+
const saved = bridge.savedResponse(slotId);
|
|
78
|
+
return typeof saved === 'object' && saved !== null && !Array.isArray(saved) ? saved : undefined;
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/** The string ids of a saved selection field, with anything else in it dropped. */
|
|
85
|
+
export function savedIds(value) {
|
|
86
|
+
return Array.isArray(value) ? value.filter((id) => typeof id === 'string') : [];
|
|
87
|
+
}
|
|
55
88
|
/**
|
|
56
89
|
* Posts the complete response map once, resolving the ticket. Only the pager's submit
|
|
57
90
|
* affordance calls this.
|
package/package.json
CHANGED
package/runtime.lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@north-light/crouter",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.195",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@north-light/crouter",
|
|
9
|
-
"version": "0.3.
|
|
9
|
+
"version": "0.3.195",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "MIT",
|
|
12
12
|
"dependencies": {
|