kanbo-cli 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +47 -0
- package/README.md +8 -7
- package/dist/cli-main.cjs +3937 -5194
- package/dist/lib/{approval-CnJJfwfi.d.mts → approval-CDiZbegu.d.mts} +20 -31
- package/dist/lib/{approval-DNfUhYD5.d.cts → approval-Nmk8UDPy.d.cts} +20 -31
- package/dist/lib/index.cjs +65 -66
- package/dist/lib/index.d.cts +5 -8
- package/dist/lib/index.d.mts +5 -8
- package/dist/lib/index.mjs +2 -2
- package/dist/lib/mcp/index.cjs +39 -40
- package/dist/lib/mcp/index.d.cts +3 -3
- package/dist/lib/mcp/index.d.mts +3 -3
- package/dist/lib/mcp/index.mjs +2 -2
- package/dist/lib/{manifest-BFI4HGPh.cjs → tool-names-BOUJas7m.cjs} +1006 -2259
- package/dist/lib/{manifest-DHI1fkoW.mjs → tool-names-CrvHZ-ON.mjs} +1009 -2256
- package/dist/page/board.css +2058 -842
- package/dist/page/board.js +5 -2
- package/dist/page/fonts/LICENSE +93 -0
- package/dist/page/fonts/geist-cyrillic-wght-normal.woff2 +0 -0
- package/dist/page/fonts/geist-latin-ext-wght-normal.woff2 +0 -0
- package/dist/page/fonts/geist-latin-wght-normal.woff2 +0 -0
- package/package.json +1 -1
package/dist/page/board.js
CHANGED
|
@@ -1,2 +1,5 @@
|
|
|
1
|
-
(function(){var e=class extends Error{status;code;constructor(e,t,n){super(n),this.status=e,this.code=t}};function t(t,r=()=>``){async function i(r,i,a){let o={},s=t();s&&(o.authorization=`Bearer ${s}`),r!==`GET`&&(o[`content-type`]=`application/json`);let c;try{c=await fetch(i,{method:r,headers:o,body:a===void 0?void 0:JSON.stringify(a)})}catch{throw new e(0,`server_unreachable`,`The board server has stopped. Run kanbo serve to open it again.`)}let l=await c.text();if(!c.ok){let t=n(l);throw new e(c.status,t?.code??`unknown`,t?.message??`${c.status} ${c.statusText}`)}return JSON.parse(l)}let a=e=>`${r()}${e}`,o=e=>a(`/issues/${encodeURIComponent(e)}`);return{projects:async()=>await i(`GET`,`/projects`),workspace:async()=>await i(`GET`,a(`/issues/workspace`)),version:async()=>(await i(`GET`,a(`/issues/version`))).seq,statuses:async()=>await i(`GET`,a(`/issues/statuses`)),cards:async()=>await i(`GET`,a(`/issues`)),createCard:async e=>await i(`POST`,a(`/issues`),e),moveCard:async(e,t)=>await i(`PATCH`,`${o(e)}/status/${encodeURIComponent(t)}`),comments:async e=>await i(`GET`,`${o(e)}/comments`),addComment:async(e,t)=>await i(`POST`,`${o(e)}/comments`,{content:t}),activity:async e=>await i(`GET`,`${o(e)}/activity`),runs:async e=>await i(`GET`,`${o(e)}/runs`),fieldChanges:async e=>await i(`GET`,`${o(e)}/field-changes`),approve:async(e,t)=>await i(`POST`,`${o(e)}/approve`,{comment:t}),returnCard:async(e,t)=>await i(`POST`,`${o(e)}/return`,{comment:t})}}function n(e){try{return JSON.parse(e)}catch{return null}}function r(e){return e.title===e.id?i(e.description)??e.title:e.title}function i(e){for(let t of(e??``).split(`
|
|
2
|
-
`)){let e=a(t);if(e)return e.length>120?`${e.slice(0,119).trimEnd()}…`:e}return null}function a(e){return e.replace(/^\s*(?:>\s*)+/,``).replace(/^\s*#{1,6}\s+/,``).replace(/^\s*(?:[-*+]|\d+[.)])\s+(?:\[[ x]\]\s+)?/i,``).replace(/!\[([^\]]*)\]\([^)]*\)/g,`$1`).replace(/\[([^\]]*)\]\([^)]*\)/g,`$1`).replace(/<[^>]+>/g,``).replace(/[*_~`]/g,``).replace(/\s+/g,` `).trim()}function o(e,t,n){let r=document.createElement(e);return t&&(r.className=t),n!==void 0&&(r.textContent=n),r}function s(e,t,n){let r=o(`button`,t,e);return r.type=`button`,r.addEventListener(`click`,n),r}let c={text:``,worker:null,waiting:!1,running:!1,priorities:[],labels:[]},l=[`urgent`,`high`,`medium`,`low`,`none`];function u(e){return e.activeRun?.state===`running`&&e.activeRun.agentName?{key:`agent:${e.activeRun.agentName}`,label:e.activeRun.agentName}:e.delegateAgentId?{key:`agent:${e.delegateAgentId}`,label:e.delegateAgentId}:e.assigneeKind===`user`?{key:`user`,label:`You`}:e.assigneeKind===`agent`&&e.assigneeId?{key:`agent:${e.assigneeId}`,label:e.assigneeId}:null}function d(e,t){let n=t.text.trim().toLowerCase();if(n&&![e.id,e.title,e.description,e.statusLine,...e.labels].some(e=>e?.toLowerCase().includes(n)))return!1;if(t.worker!==null){let n=u(e);if(t.worker===`nobody`?n!==null:n?.key!==t.worker)return!1}return!(t.waiting&&e.waitingFor!==`human`||t.running&&e.activeRun?.state!==`running`||t.priorities.length>0&&!t.priorities.includes(e.priority)||t.labels.length>0&&!e.labels.some(e=>t.labels.includes(e)))}function f(e){let t=/* @__PURE__ */ new Map,n=/* @__PURE__ */ new Set;for(let r of e){let e=u(r);e&&t.set(e.key,e.label);for(let e of r.labels)n.add(e)}return{workers:[...t].map(([e,t])=>({key:e,label:t})).sort((e,t)=>e.label.localeCompare(t.label)),labels:[...n].sort((e,t)=>e.localeCompare(t))}}function p(e){return e.text.trim()!==``||e.worker!==null||e.waiting||e.running||e.priorities.length>0||e.labels.length>0}function m(e){return e?e.split(`,`).filter(e=>e!==``):[]}function h(e){let t=new URLSearchParams(e);return{text:t.get(`q`)??``,worker:t.get(`who`)||null,waiting:t.get(`waiting`)===`1`,running:t.get(`running`)===`1`,priorities:m(t.get(`priority`)).filter(e=>l.includes(e)),labels:m(t.get(`label`))}}function g(e,t){let n=new URLSearchParams(t),r=(e,t)=>{t?n.set(e,t):n.delete(e)};r(`q`,e.text.trim()===``?null:e.text),r(`who`,e.worker),r(`waiting`,e.waiting?`1`:null),r(`running`,e.running?`1`:null),r(`priority`,e.priorities.join(`,`)||null),r(`label`,e.labels.join(`,`)||null);let i=n.toString();return i?`?${i}`:``}function _(e,t){return e.waitingFor===`human`?`waiting`:e.activeRun?.state===`running`?`running`:t===`completed`?`done`:t===`canceled`?`quiet`:`idle`}function v(e){let t=`${e.done} of ${e.total} sub-cards done`;return{chip:e.done===e.total?`All ${e.total} sub-cards done`:`${e.done}/${e.total} sub-cards`,words:t}}function ee(e,t,n,i){let a=o(`article`,`card`);a.draggable=!0,a.dataset.cardId=e.id,a.dataset.state=_(e,t);let s=e.waitingFor===`human`,c=e.activeRun?.state===`running`?e.activeRun:null,l=e.attemptCount>1;if(s||c||l){let t=o(`div`,`card-state`);if(s&&t.append(o(`span`,`waiting-badge`,`Waiting for you`)),c){let e=o(`span`,`run-state`),n=o(`span`,`run-dot`);n.setAttribute(`aria-hidden`,`true`),e.append(n,c.agentName?`Running · ${c.agentName}`:`Running`),t.append(e)}if(l){let n=o(`span`,`attempt-chip`,`×${e.attemptCount}`);n.title=`Attempt ${e.attemptCount}`,t.append(n)}a.append(t)}if(i&&e.parentIssueId){let t=i.parent,n=o(t?`button`:`span`,`parent-link`);if(n.append(o(`span`,`parent-arrow`,`↳ `),o(`span`,`card-key`,e.parentIssueId)),t){let e=n;e.type=`button`,n.append(o(`span`,`parent-title`,r(t))),n.title=`Parent: ${r(t)}`,n.addEventListener(`click`,e=>{e.stopPropagation(),i.onOpenCard(t.id)})}a.append(n)}let d=o(`button`,`card-title`,r(e));d.type=`button`,d.addEventListener(`click`,()=>n(e)),a.append(d);let f=o(`div`,`card-meta`);f.append(o(`span`,`card-key`,e.id));let p=u(e);if(p&&!c?.agentName){let e=o(`span`,`worker`,p.label);e.dataset.kind=p.key===`user`?`user`:`agent`,f.append(e)}if(i?.summary){let{chip:e,words:t}=v(i.summary),n=o(`span`,`subcard-chip`,e);n.title=t,f.append(n)}a.append(f);let m=e.statusLine?.trim()??``;if(m){let e=o(`p`,`status-line`,m);e.title=m,e.dataset.category=t??`unstarted`,a.append(e)}if(e.priority!==`none`||e.labels.length>0){let t=o(`div`,`card-tags`);if(e.priority!==`none`){let n=o(`span`,`priority`,e.priority);n.dataset.priority=e.priority,t.append(n)}t.append(...e.labels.map(e=>o(`span`,`label`,e))),a.append(t)}return a}function te(e){return new Map(e.map(e=>[e.id,{statusId:e.statusId,waiting:e.waitingFor===`human`}]))}function ne(e,t){if(e===null)return null;let n=e.get(t.id);return n?n.statusId===t.statusId?null:`moved`:`new`}function re(e,t){return e!==null&&t.waitingFor===`human`&&e.get(t.id)?.waiting!==!0}let ie={urgent:`Urgent`,high:`High`,medium:`Medium`,low:`Low`,none:`None`};function y(e,t,n,r){let i=s(e,`${t}${n?` active`:``}`,r);return i.setAttribute(`aria-pressed`,String(n)),i}function b(e,t){return e.filter(e=>e!==t)}function ae(e,t,n,r){let i=o(`div`,`filter-bar`);i.setAttribute(`role`,`search`);let a=o(`input`,`field filter-search`);a.type=`search`,a.placeholder=`Search cards`,a.setAttribute(`aria-label`,`Search cards`),a.value=e.text,a.addEventListener(`input`,()=>r({...e,text:a.value})),a.addEventListener(`keydown`,t=>{t.key===`Escape`&&a.value!==``&&(t.stopPropagation(),a.value=``,r({...e,text:``}))});let u=o(`select`,`field filter-worker`);u.setAttribute(`aria-label`,`Worked by`);let d=[{key:``,label:`Anyone`},{key:`nobody`,label:`Nobody`},...t.workers];e.worker!==null&&!d.some(t=>t.key===e.worker)&&d.push({key:e.worker,label:e.worker});for(let e of d){let t=o(`option`,void 0,e.key===``?`Worked by: Anyone`:e.label);t.value=e.key,u.append(t)}u.value=e.worker??``,u.addEventListener(`change`,()=>r({...e,worker:u.value===``?null:u.value}));let f=o(`span`,`filter-group`);f.setAttribute(`role`,`group`),f.setAttribute(`aria-label`,`Priority`);for(let t of l){let n=e.priorities.includes(t);f.append(y(ie[t],`filter-chip`,n,()=>r({...e,priorities:n?b(e.priorities,t):[...e.priorities,t]})))}let m=o(`span`,`select-wrap`);m.append(u);let h=y(`Waiting for you`,`filter-toggle`,e.waiting,()=>r({...e,waiting:!e.waiting}));h.dataset.filter=`waiting`;let g=y(`Running now`,`filter-toggle`,e.running,()=>r({...e,running:!e.running}));g.dataset.filter=`running`,i.append(a,m,h,g,f);let _=[.../* @__PURE__ */ new Set([...t.labels,...e.labels])];if(_.length>0&&_.length<=8){let t=o(`span`,`filter-group`);t.setAttribute(`role`,`group`),t.setAttribute(`aria-label`,`Labels`);for(let n of _){let i=e.labels.includes(n);t.append(y(n,`filter-chip`,i,()=>r({...e,labels:i?b(e.labels,n):[...e.labels,n]})))}i.append(t)}else if(_.length>8){let t=o(`select`,`field filter-labels`);t.multiple=!0,t.setAttribute(`aria-label`,`Labels`);for(let n of _){let r=o(`option`,void 0,n);r.value=n,r.selected=e.labels.includes(n),t.append(r)}t.addEventListener(`change`,()=>r({...e,labels:[...t.selectedOptions].map(e=>e.value)})),i.append(t)}return p(e)&&i.append(o(`span`,`filter-count`,oe(n)),s(`Clear`,`ghost filter-clear`,()=>r(c))),i}function oe(e){return`Showing ${e.shown} of ${e.total}`}function se(e,t){let n=e.querySelector(`.filter-count`);n&&(n.textContent=oe(t))}function ce(e,t){let n=new Set(t.map(e=>e.statusId)),r=e.filter(e=>e.category!==`canceled`||n.has(e.id)).map(e=>({id:e.id,name:e.name,status:e,cards:[]})),i=new Map(r.map(e=>[e.id,e])),a=new Set(e.map(e=>e.id));for(let e of t){let t=e.statusId??``,n=i.get(t);!n&&!a.has(t)&&(n={id:t,name:e.statusId??`No status`,status:null,cards:[]},i.set(t,n),r.push(n)),n?.cards.push(e)}return r}function le(e){switch(e){case`assignee`:return`Assignee`;case`description`:return`Description`;case`due-date`:return`Due date`;case`labels`:return`Labels`;case`metadata`:return`Metadata`;case`milestone`:return`Milestone`;case`parent`:return`Parent card`;case`priority`:return`Priority`;case`status`:return`Column`;case`status-line`:return`Status line`;case`title`:return`Title`;case`workspace`:return`Workspace`}}function ue(e,t){let n=new Map(t.map(e=>[e.id,e])),r=[];for(let t of e){if(t.kind===`comment`)continue;let e={kind:t.actor.kind,name:t.actor.displayName,label:t.actor.label},i={id:t.id,actor:e,field:null,from:null,to:null,text:null,at:t.createdAt},a=t.fieldChange;if(t.kind===`created`)r.push({...i,verb:`created the card`});else if(!a)r.push({...i,verb:`changed the card`});else if(a.action===`added-description`||a.action===`updated-description`||a.action===`cleared-description`){let e=n.get(t.id),o=a.action===`added-description`?`added the description`:a.action===`cleared-description`?`cleared the description`:`updated the description`;r.push({...i,verb:o,text:e?{before:e.fromValue,after:e.toValue}:null})}else if(a.field===`metadata`||a.field===null)r.push({...i,verb:`changed metadata`});else{let e=a.field===`status`?`moved it`:a.action===`renamed-issue`?`renamed it`:`changed`;r.push({...i,verb:e,field:le(a.field),from:de(a.fromValue),to:de(a.toValue)})}}return[...r].sort((e,t)=>t.at-e.at)}function de(e){if(!e)return`nothing`;if(e.kind===`text`)return e.text;if(e.kind===`date`)return(/* @__PURE__ */ new Date(e.timestamp*1e3)).toLocaleDateString();if(e.token.startsWith(`priority-`)){let t=e.token.slice(9);return`${t.charAt(0).toUpperCase()}${t.slice(1)}`}return e.token===`current-user`?`you`:e.token.replaceAll(`-`,` `)}function x(e,t){return e.getFullYear()===t.getFullYear()&&e.getMonth()===t.getMonth()&&e.getDate()===t.getDate()}function fe(e,t){return e.toLocaleDateString(void 0,{day:`numeric`,month:`short`,year:e.getFullYear()===t.getFullYear()?void 0:`numeric`})}function pe(e,t){return x(e,t)?`Today`:x(e,new Date(t.getFullYear(),t.getMonth(),t.getDate()-1))?`Yesterday`:fe(e,t)}function me(e,t){let n=[];for(let r of e){let e=pe(/* @__PURE__ */ new Date(r.at*1e3),t),i=n.at(-1);i&&i.day===e?i.entries.push(r):n.push({day:e,entries:[r]})}return n}function he(e,t){let n=/* @__PURE__ */ new Date(e*1e3);if(!x(n,t))return _e(n);let r=Math.floor(t.getTime()/1e3)-e;return r<60?`just now`:r<3600?`${Math.floor(r/60)} min ago`:`${Math.floor(r/3600)} h ago`}function ge(e,t,{withClock:n=!1}={}){let r=/* @__PURE__ */ new Date(e*1e3);return x(r,t)?he(e,t):n?`${pe(r,t)} ${_e(r)}`:pe(r,t)}function _e(e){return e.toLocaleTimeString(void 0,{hour:`2-digit`,minute:`2-digit`})}let S=[{tab:`comments`,label:`Comments`},{tab:`history`,label:`History`},{tab:`runs`,label:`Runs`}];function ve(e,t){return e.querySelector(`.panel-head .card-key`)?.textContent===t?e.querySelector(`.panel-scroll`)?.scrollTop??0:0}function ye(e,t,n){let{card:i,status:a}=e,c=o(`div`,`panel`);c.setAttribute(`role`,`dialog`),c.setAttribute(`aria-modal`,`true`);let l=`panel-title`;c.setAttribute(`aria-labelledby`,l);let u=o(`div`,`panel-head`),d=s(`✕`,`icon-button`,t.close);d.setAttribute(`aria-label`,`Close`),d.title=`Close (Esc)`,u.append(o(`span`,`card-key`,i.id),o(`span`,`spacer`),d);let f=o(`div`,`panel-scroll`),p=o(`div`,`panel-top`),m=o(`h2`,`panel-title`,r(i));m.id=l,p.append(m,be(i,a));let h=ue(e.activity,e.fieldChanges),g=/* @__PURE__ */ new Date;if(i.statusLine?.trim()){let e=o(`p`,`status-line`,i.statusLine.trim());e.dataset.category=a?.category??`unstarted`,p.append(e)}let _=o(`p`,`panel-notice`,n??``);_.setAttribute(`role`,`alert`),_.hidden=!n,p.append(_);let v=o(`div`,`panel-main`);v.append(w(`Description`,i.description?.trim()?o(`div`,`description`,i.description):o(`p`,`empty`,`No description.`))),e.children.length>0&&v.append(we(e,t));let ee=[...Oe(e.comments,t,g)],te=[Te(h,g)],ne=[Ae(e.runs,e=>[je(e),e.startedAt,e.state],`No runs.`,g)],re={comments:e.comments.length,history:h.length,runs:e.runs.length},ie={comments:ee,history:te,runs:ne};v.append(xe(e.tab,re,ie,t));let y=o(`div`,`panel-side`);y.append(De(i,t),w(`Details`,Ce(i,e.parent,e.runs,t,h,g)));let b=o(`div`,`panel-body`);return b.append(v,y),f.append(p,b),c.append(u,f),c}function be(e,t){let n=o(`div`,`state-row`);if(n.append(o(`span`,`column-pill`,t?t.name:`No column`)),e.waitingFor===`human`&&n.append(o(`span`,`waiting-badge`,`Waiting for you`)),e.activeRun?.state===`running`){let t=o(`span`,`run-state`),r=o(`span`,`run-dot`);r.setAttribute(`aria-hidden`,`true`),t.append(r,e.activeRun.agentName?`Running · ${e.activeRun.agentName}`:`Running`),n.append(t)}return n}function xe(e,t,n,r){let i=o(`div`,`tabs-wrap`),a=o(`div`,`tabs`);a.setAttribute(`role`,`tablist`);let s=[],c=/* @__PURE__ */ new Map,l=/* @__PURE__ */ new Map,u=e=>{for(let[t,n]of c)n.setAttribute(`aria-selected`,String(t===e)),n.tabIndex=t===e?0:-1,l.get(t).hidden=t!==e;r.selectTab(e)};return S.forEach(({tab:r,label:i},d)=>{let f=o(`button`,`tab`);f.type=`button`,f.id=`tab-${r}`,f.setAttribute(`role`,`tab`),f.setAttribute(`aria-selected`,String(r===e)),f.setAttribute(`aria-controls`,`tab-panel-${r}`),f.tabIndex=r===e?0:-1,f.append(i,o(`span`,`count`,String(t[r]))),f.addEventListener(`click`,()=>u(r)),f.addEventListener(`keydown`,e=>{if(e.key!==`ArrowLeft`&&e.key!==`ArrowRight`)return;e.preventDefault();let t=S[(d+(e.key===`ArrowRight`?1:S.length-1))%S.length].tab;u(t),c.get(t)?.focus()}),c.set(r,f),a.append(f);let p=o(`div`,`tab-panel`);p.id=`tab-panel-${r}`,p.setAttribute(`role`,`tabpanel`),p.setAttribute(`aria-labelledby`,f.id),p.hidden=r!==e,p.append(...n[r]),l.set(r,p),s.push(p)}),i.append(a,...s),i}function Se(e,t){let n=/* @__PURE__ */ new Date(e*1e3),r=o(`time`,`history-time`,t);return r.dateTime=n.toISOString(),r.title=n.toLocaleString(),r}function Ce(e,t,n,i,a,s){let c=o(`dl`,`facts`),l=(e,...t)=>{let n=o(`dd`);n.append(...t),c.append(o(`dt`,void 0,e),n)};if(e.parentIssueId){if(t){let e=o(`button`,`link`);e.type=`button`,e.append(o(`span`,`card-key`,t.id),o(`span`,`link-title`,r(t))),e.addEventListener(`click`,()=>i.openCard(t.id)),l(`Parent`,e)}else l(`Parent`,o(`span`,`card-key`,e.parentIssueId))}let d=a.find(e=>e.verb===`created the card`);l(`Created by`,C(d?{kind:d.actor.kind,name:d.actor.name,label:d.actor.label}:{kind:e.createdByKind,name:e.createdByKind===`user`?`You`:e.createdById??e.createdByKind,label:null}),` `,o(`span`,`muted`,`· ${ge(d?.at??e.createdAt,s)}`));let f=u(e),p=f?null:n.reduce((e,t)=>e===null||t.startedAt>e.startedAt?t:e,null);if(p?l(`Worked by`,C({kind:`agent`,name:p.agentName,label:null}),` `,o(`span`,`muted`,`· ${p.state}`)):l(`Worked by`,f?C({kind:f.key===`user`?`user`:`agent`,name:f.label,label:null}):`Nobody`,...e.activeRun?.state===`running`?[` `,o(`span`,`muted`,`· running`)]:[]),e.priority!==`none`){let t=o(`span`,`priority`,e.priority);t.dataset.priority=e.priority,l(`Priority`,t)}return e.labels.length>0&&l(`Labels`,...e.labels.map(e=>o(`span`,`label`,e))),c}function we(e,t){let n=t=>e.statuses.find(e=>e.id===t.statusId)?.category===`completed`,i=e.children.filter(n).length,a=w(`Sub-cards · ${i} of ${e.children.length} done`),s=o(`ul`,`subcards`);for(let i of e.children){let a=o(`li`),c=o(`button`,`subcard`);c.type=`button`,c.dataset.done=String(n(i)),c.addEventListener(`click`,()=>t.openCard(i.id));let l=o(`span`,`subcard-head`);l.append(o(`span`,`card-key`,i.id),o(`span`,`subcard-title`,r(i)));let d=o(`span`,`subcard-meta`);d.append(o(`span`,`subcard-column`,e.statuses.find(e=>e.id===i.statusId)?.name??`No column`)),i.waitingFor===`human`&&d.append(o(`span`,`waiting-badge`,`Waiting for you`)),i.activeRun?.state===`running`&&d.append(o(`span`,`muted`,i.activeRun.agentName?`Running · ${i.activeRun.agentName}`:`Running`));let f=u(i);f&&d.append(C({kind:f.key===`user`?`user`:`agent`,name:f.label,label:null})),c.append(l,d),a.append(c),s.append(a)}return a.append(s),a}function C(e){let t=o(`span`,`actor-chip`,e.name),n=e.label===`External`;return t.dataset.kind=n||e.kind===`provider-target`?`agent`:e.kind,n?t.title=e.label??``:e.label&&t.append(o(`small`,`actor-label`,` ${e.label}`)),t}function Te(e,t){let n=w(`History`);if(e.length===0)return n.append(o(`p`,`empty`,`No history yet.`)),n;for(let r of me(e,t)){let e=o(`section`,`history-day`);e.append(o(`h4`,void 0,r.day));let i=o(`ol`,`history-list`);for(let e of r.entries)i.append(Ee(e,t));e.append(i),n.append(e)}return n}function Ee(e,t){let n=o(`li`,`history-entry`);n.dataset.kind=e.actor.label===`External`||e.actor.kind===`provider-target`?`agent`:e.actor.kind;let r=o(`span`,`history-what`);if(r.append(C(e.actor),` ${e.verb}`),e.field&&r.append(` `,o(`span`,`history-field`,e.field)),n.append(r,Se(e.at,he(e.at,t))),e.from!==null||e.to!==null){let t=o(`span`,`history-change`);e.from!==null&&t.append(o(`del`,`value-from`,e.from)),e.to!==null&&t.append(o(`ins`,`value-to`,e.to)),n.append(t)}if(e.text){let t=o(`details`,`history-text`);t.append(o(`summary`,void 0,`Show before / after`));let r=o(`div`,`history-text-pair`);for(let[t,n,i]of[[`before`,`Before`,e.text.before],[`after`,`After`,e.text.after]]){let e=o(`p`,`history-text-block`);e.dataset.side=t,e.append(o(`b`,void 0,n),i??``),r.append(e)}t.append(r),n.append(t)}return n}function w(e,...t){let n=o(`section`,`panel-section`);return n.append(o(`h3`,void 0,e),...t),n}function De(e,t){let n=o(`textarea`,`field`);n.rows=2,n.placeholder=e.waitingFor===`human`?`A note for the agent (needed to return)`:`Why it goes back (needed to return)`,n.setAttribute(`aria-label`,`Decision note`);let r=o(`p`,`hint`),i=o(`div`,`row`);e.waitingFor===`human`&&i.append(s(`Approve`,`primary`,()=>t.approve(n.value.trim()||null))),i.append(s(`Return`,`secondary`,()=>{let e=n.value.trim();if(!e){r.textContent=`Say why in the note to return the card.`,n.focus();return}t.returnCard(e)}));let a=w(`Decision`,n,i,r);return e.waitingFor===`human`&&(a.dataset.waiting=``),a}function Oe(e,t,n){if(e.length===0)return[ke(t),o(`p`,`empty`,`No comments.`)];let r=o(`ul`,`entries`);for(let t of[...e].reverse()){let e=o(`li`),i=o(`div`,`entry-meta`);i.append(C({kind:t.author.kind,name:t.author.displayName,label:t.author.label}),Se(t.createdAt,ge(t.createdAt,n,{withClock:!0}))),e.append(i,o(`div`,`entry-text`,t.content)),r.append(e)}return[ke(t),r]}function ke(e){let t=o(`div`,`comment-form`),n=o(`textarea`,`field`);return n.rows=4,n.placeholder=`Add a comment`,n.setAttribute(`aria-label`,`New comment`),t.append(n,s(`Comment`,`secondary`,()=>{let t=n.value.trim();t&&e.addComment(t)})),t}function Ae(e,t,n,r){if(e.length===0)return o(`p`,`empty`,n);let i=o(`ul`,`entries`);for(let n of e){let[e,a,s]=t(n),c=o(`li`);c.dataset.runState=s;let l=o(`div`,`entry-meta`);l.append(Se(a,ge(a,r,{withClock:!0}))),c.append(o(`div`,`entry-text`,e),l),i.append(c)}return i}function je(e){return[`Attempt ${e.attempt}`,e.agentName,e.state,e.branch].filter(Boolean).join(` · `)}function Me(e,t,n){let r=e=>{let n=t.findIndex(t=>t.id===e.statusId);return n===-1?t.length:n};return e.filter(e=>e.parentIssueId===n&&e.id!==n).sort((e,t)=>r(e)-r(t)||e.order-t.order)}function Ne(e,t,n){let r=e=>t.find(t=>t.id===e.statusId)?.category,i=Me(e,t,n).filter(e=>r(e)!==`canceled`);return i.length===0?null:{total:i.length,done:i.filter(e=>r(e)===`completed`).length}}function Pe(e,t){return!t.parentIssueId||t.parentIssueId===t.id?null:e.find(e=>e.id===t.parentIssueId)??null}function Fe(e=globalThis.crypto){return typeof e.randomUUID==`function`?e.randomUUID():Array.from(e.getRandomValues(/* @__PURE__ */ new Uint8Array(16)),e=>e.toString(16).padStart(2,`0`)).join(``)}function Ie(e){let t=Fe(),n=null;function r(r){let i={"content-type":`application/json`},a=e();a&&(i.authorization=`Bearer ${a}`),fetch(`/page/presence`,{method:`POST`,keepalive:!0,headers:i,body:JSON.stringify({tabId:t,state:r})}).then(e=>{(e.status===404||e.status===204)&&n!==null&&(clearInterval(n),n=null)},()=>{})}r(`open`),n=setInterval(()=>r(`open`),2e4),window.addEventListener(`pagehide`,()=>r(`closed`)),window.addEventListener(`pageshow`,e=>{e.persisted&&r(`open`)})}function Le(e,t,n,r=null){let i=o(`label`,`project-switcher select-wrap`);i.append(o(`span`,`visually-hidden`,`Project`));let a=o(`select`,`field project-select`);if(r){let e=o(`option`,void 0,`${r.name?`${r.name} · `:``}the board this server was started on`);e.value=``,e.selected=t===null,a.append(e)}for(let n of e){let e=o(`option`,void 0,`${n.name} · ${n.folder}`);e.value=n.id,e.selected=n.id===t,a.append(e)}return a.addEventListener(`change`,()=>n(a.value)),i.append(a),i}function Re(e,t){let n=o(`span`,`project-where`);if(n.append(o(`span`,`where-key`,t.identifier)),!e)return t.name&&n.append(` · ${t.name}`),n;let r=e.storage.kind===`file`?`board file ${e.storage.path}`:`Postgres at ${e.storage.where}`;return n.append(` · ${e.folder} · ${r}`),n}let ze=`kanbo-serve-token`;function Be(){try{return sessionStorage.getItem(ze)}catch{return null}}function Ve(e){try{e?sessionStorage.setItem(ze,e):sessionStorage.removeItem(ze)}catch{}}function He(){let e=new URLSearchParams(location.hash.slice(1)).get(`token`)?.trim();e&&(Ve(e),history.replaceState(history.state,``,`${location.pathname}${location.search}`))}He();let T=Be(),E=new URLSearchParams(location.search).get(`project`),D=[],O=null,Ue=``,k=t(()=>T,()=>E===null?``:`/projects/${encodeURIComponent(E)}`),A=h(location.search),We=``,j=[],M=[],Ge=null,N=!1,Ke=!1,P=!1,F=null,I=null,L=null,R=null,z=null,B=null,qe=document.querySelector(`#app`)??document.body,V=o(`header`,`topbar`),H=o(`input`,`field token-input`),Je=s(`Token`,`ghost token-toggle`,()=>{q=!q,J(),q&&H.focus()}),U=o(`p`,`notice`),W=o(`main`,`board`),G=o(`div`,`panel-host`),Ye=o(`span`,`project-slot`),K=o(`div`,`filter-slot`),Xe=!1,q=!1;function J(){T===null||N||!Xe?(q=!1,delete V.dataset.token):V.dataset.token=q?`unfolded`:`folded`,Je.setAttribute(`aria-expanded`,String(V.dataset.token!==`folded`))}function Ze(){qe.classList.add(`app`);let e=o(`h1`,`topbar-title`,`Kanbo`),t=o(`span`,`workspace`);t.id=`workspace`,Ye.id=`project-switcher`;let n=o(`form`,`token-form`);n.id=`token-form`,Je.setAttribute(`aria-controls`,n.id),H.type=`password`,H.autocomplete=`off`,H.placeholder=`Server token`,H.value=T??``;let r=o(`label`,`token-label`,`Token`);r.append(H);let i=o(`button`,`secondary`,`Save`);i.type=`submit`,n.append(r,i),n.addEventListener(`submit`,e=>{e.preventDefault(),T=H.value.trim()||null,Ve(T),N=!1,q=!1,X(null),Q()}),V.append(e,Ye,Je,t,n),J(),U.setAttribute(`role`,`status`),U.hidden=!0,qe.replaceChildren(V,U,K,W,G)}let Y=!1;function X(e,t=`info`){U.textContent=e??``,U.hidden=!e,U.dataset.kind=t,Y=!1}function Z(t){return t instanceof e?t.code===`server_unreachable`?(Ke=!0,t.message):t.status===401?(N=!0,J(),H.focus(),`This server needs its token. Enter it in the Token field above.`):t.message:t instanceof Error?t.message:String(t)}function Qe(e){X(Z(e),`error`),Y=!0,Xe=!1,J()}function $e(){Xe=!0,J(),Y&&(Y=!1,X(null))}async function Q(){if(!P){P=!0;try{let e=await k.version(),[t,n,r,i]=await Promise.all([k.statuses(),k.cards(),k.projects(),k.workspace()]);Ge=e,j=t,M=n,D=r,O=i,st(),$e(),I&&await ht()}catch(e){tt(e)||Qe(e)}finally{P=!1}et&&(et=!1,await Q())}}let et=!1;function tt(t){if(!(t instanceof e)||t.code!==`project_not_found`||E===null)return!1;let n=D.find(e=>e.isDefault);return nt(null),X(`That project is no longer on this computer's list; showing ${n?.name??`the board this server was started on`}.`),et=!0,!0}function nt(e){E=e;let t=new URL(location.href);e===null?t.searchParams.delete(`project`):t.searchParams.set(`project`,e),A={...A,worker:null,labels:[]},at(t),Ge=null,F=null,$(),j=[],M=[],B=null,O=null,Ue=``,X(null)}async function rt(){if(!(document.visibilityState!==`visible`||N||Ke||P))try{await k.version()===Ge?$e():await Q()}catch(e){tt(e)?await Q():Qe(e)}}function it(){let e=E===null?D.find(e=>e.isDefault)??null:D.find(e=>e.id===E)??null,t=JSON.stringify([D,E,e?.id,O]);if(t===Ue)return;Ue=t;let n=D.some(e=>e.isDefault);Ye.replaceChildren(...D.length>+!!n?[Le(D,e?.id??null,e=>{nt(e===``?null:e),Q()},n?null:{name:E===null?O?.name??null:null})]:[]);let r=document.querySelector(`#workspace`);r&&r.replaceChildren(...O?[Re(e,O)]:[])}function at(e=new URL(location.href)){history.replaceState(null,``,`${e.pathname}${g(A,e.search)}${e.hash}`)}function ot(e){A=e,at(),st()}function st(){it();let e=F!==null&&document.activeElement===F.input,t=document.activeElement?.closest(`.card`)?.dataset.cardId??null,n=K.querySelector(`.filter-search`),r=n!==null&&document.activeElement===n,i=n?[n.selectionStart,n.selectionEnd,n.selectionDirection]:null,a=M.filter(e=>d(e,A)),o={shown:a.length,total:M.length},s=f(M),c=JSON.stringify([A,s]);if(c!==We||!K.firstElementChild?(We=c,K.replaceChildren(ae(A,s,o,ot))):se(K.firstElementChild,o),W.replaceChildren(...ce(j,a).map(ut)),B=te(M),ct(),r){let e=K.querySelector(`.filter-search`);e?.focus(),e&&i&&e.setSelectionRange(i[0],i[1],i[2]??void 0)}else e?F?.input.focus():t&<(t)}function ct(){for(let e of W.querySelectorAll(`.card`))e.toggleAttribute(`data-open`,e.dataset.cardId===I)}function lt(e){for(let t of W.querySelectorAll(`.card`))t.dataset.cardId===e&&t.querySelector(`.card-title`)?.focus()}function ut(e){let t=o(`section`,`column`);t.setAttribute(`aria-label`,e.name);let n=o(`header`,`column-head`);n.append(o(`span`,`column-name`,e.name),o(`span`,`column-count`,String(e.cards.length)));let r=e.status;if(r){let t=s(`+ New`,`ghost column-add`,()=>ft(r));t.setAttribute(`aria-label`,`New card in ${e.name}`),n.append(t)}let i=o(`div`,`column-cards`);F&&F.statusId===e.id&&i.append(F.form);for(let t of e.cards){let e=ee(t,r?.category??null,e=>void mt(e.id),{parent:Pe(M,t),summary:Ne(M,j,t.id),onOpenCard:e=>void mt(e)}),n=ne(B,t);n&&(e.dataset.enter=n),re(B,t)&&e.querySelector(`.waiting-badge`)?.setAttribute(`data-enter`,`waiting`),e.addEventListener(`dragstart`,n=>{z=t.id,n.dataTransfer?.setData(`text/plain`,t.id),e.classList.add(`dragging`)}),e.addEventListener(`dragend`,()=>{z=null,e.classList.remove(`dragging`)}),i.append(e)}return t.append(n,i),r&&(t.addEventListener(`dragover`,e=>{z&&(e.preventDefault(),t.classList.add(`drop-target`))}),t.addEventListener(`dragleave`,e=>{t.contains(e.relatedTarget)||t.classList.remove(`drop-target`)}),t.addEventListener(`drop`,e=>{e.preventDefault(),t.classList.remove(`drop-target`);let n=z;z=null,n&&dt(n,r)})),t}async function dt(e,t){if(M.find(t=>t.id===e)?.statusId!==t.id){try{let n=await k.moveCard(e,t.id),r=n.unmetRules??[];X(r.length>0?`${n.id} is in ${t.name}, but still misses: ${r.map(e=>e.detail).join(`; `)}`:null)}catch(e){X(Z(e),`error`)}await Q()}}function ft(e){let t=o(`div`,`draft`),n=o(`textarea`,`field`);n.rows=3,n.placeholder=`Describe the card`,n.setAttribute(`aria-label`,`New card in ${e.name}`);let r=async()=>{let t=n.value.trim();if(!t){n.focus();return}try{let n=await k.createCard({workspaceId:e.workspaceId,statusId:e.id,description:t});F=null,X(n.unmetRules?.length?`${n.id} is in ${e.name}, but still misses: ${n.unmetRules.map(e=>e.detail).join(`; `)}`:null)}catch(e){X(Z(e),`error`)}await Q()},i=()=>{F=null,st()};n.addEventListener(`keydown`,e=>{e.key===`Enter`&&(e.metaKey||e.ctrlKey)?(e.preventDefault(),r()):e.key===`Escape`&&(e.stopPropagation(),i())});let a=o(`div`,`row`);a.append(s(`Create`,`primary`,()=>void r()),s(`Cancel`,`ghost`,i)),t.append(n,a),F={statusId:e.id,form:t,input:n},st(),n.focus()}let pt=`comments`;async function mt(e){I=e,R=null,ct(),await ht()}async function ht(){let e=I,t=M.find(t=>t.id===e);if(!e||!t){$();return}if(!(L?.card.id===e&>(G))){try{let[n,r,i,a]=await Promise.all([k.comments(e),k.activity(e),k.runs(e),k.fieldChanges(e)]);L={card:t,status:j.find(e=>e.id===t.statusId)??null,comments:n,activity:r,runs:i,fieldChanges:a,parent:Pe(M,t),children:Me(M,j,e),statuses:j,tab:pt}}catch(e){R=Z(e)}_t()}}function gt(e){return[...e.querySelectorAll(`textarea`)].some(e=>e.value.trim()!==``||document.activeElement===e)}function _t(){if(!L||L.card.id!==I){G.replaceChildren(),yt(!1);return}let e=L.card.id,t=ye(L,{close:$,addComment:t=>void vt(async()=>{await k.addComment(e,t)}),approve:t=>void vt(async()=>{await k.approve(e,t)}),returnCard:t=>void vt(async()=>{await k.returnCard(e,t)}),openCard:e=>void mt(e),selectTab:e=>{pt=e,L&&={...L,tab:e}}},R),n=!G.firstChild,r=ve(G,e);G.replaceChildren(t);let i=t.querySelector(`.panel-scroll`);i&&(i.scrollTop=r),n&&(yt(!0),t.classList.add(`panel--opening`),t.querySelector(`button`)?.focus())}async function vt(t){try{await t(),R=null;for(let e of G.querySelectorAll(`textarea`))e.value=``}catch(t){let n=Z(t);R=t instanceof e&&t.status===403?`${n} Needs the server token: only a request holding the token this server was started with acts for a person.`:n;let r=G.querySelector(`.panel-notice`);r&&(r.textContent=R,r.hidden=!1);return}await Q()}function yt(e){for(let t of[V,U,K,W])t.inert=e}G.addEventListener(`click`,e=>{e.target===G&&$()});function $(){let e=I;I=null,L=null,R=null,G.replaceChildren(),yt(!1),ct(),e&<(e)}document.addEventListener(`keydown`,e=>{e.key===`Escape`&&I?$():e.key===`/`&&!e.metaKey&&!e.ctrlKey&&!e.altKey&&!bt(e.target)&&(e.preventDefault(),K.querySelector(`.filter-search`)?.focus())});function bt(e){return e instanceof HTMLElement&&(e.isContentEditable||[`INPUT`,`TEXTAREA`,`SELECT`].includes(e.tagName))}document.addEventListener(`visibilitychange`,()=>void rt()),Ze(),Q(),setInterval(()=>void rt(),2e3),Ie(()=>T)})();
|
|
1
|
+
(function(){let e=86400;function t(t){let n=Math.floor(t/e),r=n-(n+3)%7,i=r+3,a=(/* @__PURE__ */ new Date(i*e*1e3)).getUTCFullYear(),o=Date.UTC(a,0,1)/1e3/e,s=Math.floor((i-o)/7)+1;return{week:`${a}-W${String(s).padStart(2,`0`)}`,start:r*e}}function n(e,t,n){let r=document.createElement(e);return t&&(r.className=t),n!==void 0&&(r.textContent=n),r}function r(e,t,r){let i=n(`button`,t,e);return i.type=`button`,i.addEventListener(`click`,r),i}function i(e,t=220,n={}){return{width:e,height:t,left:n.left??32,right:e-(n.right??12),top:n.top??8,bottom:t-(n.bottom??24)}}function a(e,t=4){let n=Math.max(1,Math.ceil(e)),r=Math.max(1,Math.ceil(n/t)),i=[];for(let e=0;e<n+r&&(i.push(e),!(e>=n));e+=r);return i}function o(e,t=6){if(!(e>0))return[0,1];let n=e/t,r=10**Math.floor(Math.log10(n)),i=[1,2,5,10].map(e=>e*r).find(e=>e>=n)??r*10,a=[];for(let t=0;t<e+i&&(a.push(Number(t.toFixed(10))),!(t>=e));t+=i);return a}function s(e,t){let n=e[1]-e[0];return r=>n===0?t[0]:t[0]+(r-e[0])/n*(t[1]-t[0])}function c(e,t,n,r,i=.5,a=36){let o=(n.right-n.left)/Math.max(e.length,1),c=s([0,r],[n.bottom,n.top]);return e.map((e,r)=>{let s=Math.min(o*i,a),l=c(e);return{x:n.left+o*r+(o-s)/2,y:l,width:s,height:n.bottom-l,value:e,label:t[r]??``}})}function l(e,t){let n=[...t].reverse(),r=e.map(()=>0);return n.map(t=>({slug:t,points:e.map((e,n)=>{let i=r[n],a=i+(e.cards[t]??0);return r[n]=a,{lower:i,upper:a}})}))}function u(e){return e.reduce((e,t)=>Math.max(e,Object.values(t.cards).reduce((e,t)=>e+t,0)),0)}function d(e,t,n){if(e.length===0)return``;let r=e.map((e,r)=>`${r===0?`M`:`L`}${f(t(r))} ${f(n(e.upper))}`),i=e.map((e,r)=>`L${f(t(r))} ${f(n(e.lower))}`).reverse();return`${r.join(` `)} ${i.join(` `)} Z`}function f(e){return Math.round(e*100)/100}function p(e,t){if(e<=0||t<=0)return[];let n=Math.ceil(e/t);return Array.from({length:Math.ceil(e/n)},(e,t)=>t*n)}function m(e,t,n,r,i,a=.55){let o=s([0,r],[n.left,n.right]);return e.map((e,r)=>{let s=i*a;return{y:n.top+i*r+(i-s)/2,width:o(e)-n.left,height:s,value:e,label:t[r]??``}})}function h(e){return Math.max(120,e*32+32)}function g(e,t,n={},...r){let i=document.createElementNS(`http://www.w3.org/2000/svg`,e);t&&i.setAttribute(`class`,t);for(let[e,t]of Object.entries(n))i.setAttribute(e,String(t));for(let e of r)i.append(e);return i}function ee(e){let t=g(`title`);return t.textContent=e,t}function _(e,t,n){return g(`svg`,`chart`,{viewBox:`0 0 ${e} ${t}`,width:e,height:t,role:`img`,"aria-label":n,focusable:`false`})}function v(e,t,n,r){return g(`text`,`chart-axis`,{x:f(t),y:f(n),"text-anchor":r},e)}function y(e,t,n,r,i=String){for(let a of n)e.append(g(`line`,`chart-grid`,{x1:t.left,x2:t.right,y1:f(r(a)),y2:f(r(a))}),v(i(a),t.left-6,r(a)+3,`end`))}function b(e,t){let n=_(t,220,`Cards finished per week: ${e.reduce((e,t)=>e+t.finished,0)} in ${e.length} weeks`),r=i(t),o=a(Math.max(0,...e.map(e=>e.finished))),l=o.at(-1)??1;y(n,r,o,s([0,l],[r.bottom,r.top]));let u=c(e.map(e=>e.finished),e.map(e=>e.week),r,l),d=new Set(p(e.length,Math.max(1,Math.floor((r.right-r.left)/64))));return u.forEach((e,t)=>{n.append(g(`rect`,`chart-bar`,{x:f(e.x),y:f(e.y),width:f(e.width),height:f(e.height),rx:2},ee(`${e.label}: ${e.value} finished`))),d.has(t)&&n.append(v(e.label,e.x+e.width/2,r.bottom+14,`middle`))}),n}function x(e,t,n){let r=t.map(e=>e.slug),o=new Map(t.map(e=>[e.slug,e.name])),c=e.at(-1),f=_(n,220,`Cumulative flow over ${e.length} days: ${c?Object.values(c.cards).reduce((e,t)=>e+t,0):0} cards on the last day`),m=i(n),h=a(u(e)),b=s([0,h.at(-1)??1],[m.bottom,m.top]);y(f,m,h,b);let x=e.length===1?[e[0],e[0]]:e,ne=s([0,Math.max(x.length-1,1)],[m.left,m.right]);l(x,r).forEach((t,n)=>{let i=te(r,t.slug),a=Math.max(0,...e.map(e=>e.cards[t.slug]??0));f.append(g(`path`,`chart-area chart-series-${i}`,{d:d(t.points,ne,b),"data-layer":n},ee(`${o.get(t.slug)??t.slug}: up to ${a} cards`)))});let re=p(e.length,Math.max(1,Math.floor((m.right-m.left)/48)));for(let t of re){let n=e[t];f.append(v(n.day.slice(5),ne(e.length===1?0:t),m.bottom+14,t===0?`start`:`middle`))}return f}function te(e,t){return Math.max(0,e.indexOf(t))%8}function ne(e,t,n,r){let a=new Map(t.map(e=>[e.slug,e.name])),c=h(e.length),l=e.map(e=>e.seconds/86400),u=e.map(e=>a.get(e.slug)??e.slug),d=_(n,c,`Time in column, in days: ${u.map((e,t)=>`${e} ${r(l[t])}`).join(`, `)}`),p=i(n,c,{left:88,top:4,bottom:28}),y=o(Math.max(0,...l)),b=y.at(-1)??1,x=s([0,b],[p.left,p.right]);for(let e of y)d.append(g(`line`,`chart-grid`,{x1:f(x(e)),x2:f(x(e)),y1:p.top,y2:p.bottom}),v(String(e),x(e),p.bottom+14,`middle`));return m(l,u,p,b,(p.bottom-p.top)/Math.max(e.length,1)).forEach(e=>{d.append(v(e.label,p.left-8,e.y+e.height/2+3,`end`),g(`rect`,`chart-time-bar`,{x:p.left,y:f(e.y),width:f(Math.max(e.width,0)),height:f(e.height),rx:3},ee(`${e.label}: ${r(e.value)}`)))}),d}function re(e,t,r){let i=n(`table`,`visually-hidden`);i.append(n(`caption`,void 0,e));let a=n(`tr`);a.append(...t.map(e=>n(`th`,void 0,e)));let o=n(`thead`);o.append(a);let s=n(`tbody`);for(let e of r){let t=n(`tr`);t.append(...e.map(e=>n(`td`,void 0,String(e)))),s.append(t)}return i.append(o,s),i}let ie=[4,12,26];function ae(e,n){return e.sprint===null?e.weeks===12?{}:{from:t(n).start-(e.weeks-1)*604800}:{sprint:e.sprint}}function S(e){return e===null?`—`:e<3600?`${Math.max(0,Math.round(e/60))}m`:e<86400?`${Math.round(e/3600)}h`:`${oe((e/86400).toFixed(1))}d`}function oe(e){return e.replace(/\.0$/,``)}function se(e,t){return`${oe((t>0?e/t:0).toFixed(1))} a week`}function ce(e){return e===null?`—`:`${Math.round(e*100)}%`}function le(e){return e===null?`Unknown`:e===`__self__`?`You`:e}function ue(e,t,n){let r={metrics:null,sprints:[],loading:!1,error:null,query:{weeks:12,sprint:null}},i=!1,a=0,o=e=>{r={...r,...e},n()};async function s(n){let s=++a;o({loading:!0,error:null});try{let c=t(),[l,u]=await Promise.all([e.metrics(ae(r.query,Math.floor(Date.now()/1e3))),n&&c!==null?e.sprints(c):Promise.resolve(r.sprints)]);s===a&&i&&o({metrics:l,sprints:u,loading:!1})}catch(e){s===a&&i&&o({loading:!1,error:e instanceof Error?e.message:String(e)})}}return{state:()=>r,show:e=>{let t=r.query.weeks!==e.weeks||r.query.sprint!==e.sprint,n=i;r={...r,query:e},i=!0,(!n||t||r.metrics===null&&!r.loading)&&s(!n||r.sprints.length===0)},boardChanged:()=>{i&&s(!0)},retry:()=>{i&&s(!0)},hide:()=>{i=!1,a+=1,r.loading&&(r={...r,loading:!1})},reset:()=>{i=!1,a+=1,r={metrics:null,sprints:[],loading:!1,error:null,query:r.query}}}}let de={cycle:`From the first time a card enters a started column to the moment it is finished. p50 is the median; p85 is the time 85% of the cards beat.`,throughput:`Cards finished per week over this range.`,wip:`Cards in started columns right now, against each column's limit.`,firstPass:`Finished cards that were never sent back to an earlier column.`,planned:`The cards of this sprint, and how many of them are finished.`};function fe(e,t,r,...i){let a=n(`div`,`figure`),o=n(`abbr`,`figure-label`,e);return o.title=t,a.append(o,n(`div`,`figure-value`,r),...i.map(e=>n(`div`,`figure-detail`,e))),a}function pe(e,t){return e.columns.find(e=>e.slug===t)?.name??t}function me(e){return e.throughput.length}function he(e){let t=e.wip.map(t=>`${pe(e,t.slug)} ${t.cards}${t.limit===null?``:`/${t.limit}`}`);return t.length===0?`No started columns`:t.join(` · `)}function ge(e,t){let r=n(`div`,`figures`),i=e.finished.length,a=e.wip.reduce((e,t)=>e+t.cards,0),o=e.returns.byActorKind;if(r.append(fe(`Cycle time`,de.cycle,e.cycleTime.p50===null?`—`:`p50 ${S(e.cycleTime.p50)} · p85 ${S(e.cycleTime.p85)}`,`Lead time p50 ${S(e.leadTime.p50)} · p85 ${S(e.leadTime.p85)}`),fe(`Throughput`,de.throughput,se(i,me(e)),`${i} finished`),fe(`In progress now`,de.wip,String(a),he(e)),fe(`First-pass approval`,de.firstPass,ce(e.returns.firstPassRate),`Returns: ${e.returns.total} (people ${o.user} · agents ${o.agent} · outside ${o.external})`)),t){let e=t.cards.open+t.cards.done;r.append(fe(`Planned vs done`,de.planned,`${t.cards.done} of ${e}`,e===0?`No cards`:`${Math.round(t.cards.done/e*100)}% done`))}return r}function _e(){let e=n(`div`,`analytics-skeleton`);e.setAttribute(`aria-busy`,`true`),e.setAttribute(`aria-label`,`Loading analytics`);let t=n(`div`,`figures`);for(let e=0;e<4;e++)t.append(n(`div`,`figure skeleton`));let r=n(`div`,`panels`);for(let e=0;e<4;e++)r.append(n(`div`,`panel-card skeleton skeleton-panel`));return e.append(t,r),e}function ve(e,t){let i=n(`div`,`analytics-pickers`),a=n(`div`,`segmented`);a.setAttribute(`role`,`group`),a.setAttribute(`aria-label`,`Range`);for(let n of ie){let i=e.query.sprint===null&&e.query.weeks===n,o=r(`Last ${n} weeks`,``,()=>t.onQuery({weeks:n,sprint:null}));o.setAttribute(`aria-pressed`,String(i)),a.append(o)}let o=n(`label`,`select-wrap sprint-select`);o.append(n(`span`,`visually-hidden`,`Sprint`));let s=n(`select`,`field`),c=n(`option`,void 0,`No sprint`);c.value=``,s.append(c);for(let t of e.sprints){let e=n(`option`,void 0,t.title);e.value=t.id,s.append(e)}return s.value=e.query.sprint??``,s.addEventListener(`change`,()=>t.onQuery({weeks:e.query.weeks,sprint:s.value===``?null:s.value})),o.append(s),i.append(a,o),i}function ye(e,t,r,i,a){let o=n(`section`,`panel-card`),s=n(`h3`,`chart-title`,e),c=n(`div`,`chart-body`),l=0,u=()=>{let e=Math.floor(c.clientWidth);l=e>0?e:l||560,c.replaceChildren(r(l))};return u(),o.append(s,n(`p`,`panel-help`,t),...a?[a]:[],c,i),{element:o,redraw:()=>{let e=Math.floor(c.clientWidth);e>0&&e!==l&&u()}}}function be(e){let t=n(`ul`,`chart-legend`);for(let r of e){let e=n(`li`);e.append(n(`span`,`legend-swatch chart-series-${r.index}`),r.name),t.append(e)}return t}function xe(e,t){let r=n(`section`,`panel-card`);if(r.append(n(`h3`,`chart-title`,`Aging work`),n(`p`,`panel-help`,`Cards in started columns, oldest first. Marked when older than this range's cycle-time p85.`)),e.aging.length===0)return r.append(n(`p`,`panel-empty`,`No card is in a started column.`)),r;let i=n(`ul`,`aging-list`);for(let r of e.aging){let a=n(`li`),o=n(`button`,`aging-row`);o.type=`button`,o.dataset.cardId=r.issueId;let s=n(`span`,`aging-age`,S(r.ageSeconds));s.toggleAttribute(`data-over`,r.overCycleP85),r.overCycleP85&&(s.title=`Older than this range's cycle-time p85`),o.append(n(`span`,`card-key`,r.issueId),n(`span`,`aging-title`,r.title),n(`span`,`aging-where`,`${S(r.inColumnSeconds)} in ${pe(e,r.slug)}`),s),o.addEventListener(`click`,()=>t.onOpenCard(r.issueId)),a.append(o),i.append(a)}return r.append(i),r}function Se(e,t,r,i){let a=n(`section`,`panel-card panel-table`);if(a.append(n(`h3`,`chart-title`,e)),r.length===0)return a.append(n(`p`,`panel-empty`,i)),a;let o=n(`table`,`data-table`),s=n(`tr`);s.append(...t.map(e=>n(`th`,void 0,e)));let c=n(`thead`);c.append(s);let l=n(`tbody`);for(let e of r){let t=n(`tr`);for(let r of e){let e=n(`td`);e.append(r),t.append(e)}l.append(t)}return o.append(c,l),a.append(o),a}function Ce(e){return Se(`Agents`,[`Agent`,`Runs`,`Median run`,`Cards finished`,`Returned`],e.agents.map(e=>{let t=n(`span`),r=[`${e.runs.finished} finished`,`${e.runs.failed} failed`,`${e.runs.stopped} stopped`,...e.runs.running>0?[`${e.runs.running} running`]:[]];return t.append(n(`strong`,`runs-total`,String(e.runs.total)),` `,n(`small`,`runs-detail`,r.join(` · `))),[e.agentName,t,S(e.medianRunSeconds),String(e.cardsFinished),ce(e.returnRate)]}),`No agent has run on this board in this range.`)}function we(e){return Se(`People`,[`Person`,`Created`,`Approved`,`Returned`,`Moves`],e.people.map(e=>[le(e.id),String(e.created),String(e.approvals),String(e.returns),String(e.moves)]),`Nobody has written to this board in this range.`)}function Te(e,t){if(e.finished.length===0){let e=n(`section`,`panel-card analytics-empty`);return e.append(n(`h3`,`chart-title`,`Nothing finished in this range yet`),n(`p`,`panel-help`,`Finished per week, cumulative flow and time in column fill in once a card reaches a finished column.`)),[e]}let r=e.columns.map(e=>e.slug),i=e=>S(e*86400),a=ye(`Finished per week`,`Cards finished in each ISO week.`,t=>b(e.throughput,t),re(`Cards finished per week`,[`Week`,`Finished`],e.throughput.map(e=>[e.week,e.finished]))),o=be([...e.columns].reverse().map(e=>({name:e.name,index:te(r,e.slug)}))),s=ye(`Cumulative flow`,`Cards in each column at the end of each day, rebuilt from the moves.`,t=>x(e.cumulativeFlow,e.columns,t),re(`Cards per column at the end of each day`,[`Day`,...e.columns.map(e=>e.name)],e.cumulativeFlow.map(t=>[t.day,...e.columns.map(e=>t.cards[e.slug]??0)])),o),c=ye(`Time in column`,`Time the cards finished in this range spent in each column before they finished: where cards wait.`,t=>ne(e.timeInColumn,e.columns,t,i),re(`Days spent in each column`,[`Column`,`Days`],e.timeInColumn.map(t=>[pe(e,t.slug),S(t.seconds)])));return t.push(a,s,c),[a.element,s.element,c.element]}function Ee(e,t){let i=n(`div`,`analytics`);i.dataset.loading=String(e.loading);let a=[],o=null,s=null;if(i.append(ve(e,t)),e.error!==null&&e.metrics===null){let a=n(`div`,`analytics-error`);a.setAttribute(`role`,`alert`),a.append(n(`p`,void 0,e.error),r(`Try again`,`secondary`,t.onRetry)),i.append(a)}else if(e.metrics===null)i.append(_e());else{let o=e.metrics;if(e.error!==null){let a=n(`div`,`analytics-error`);a.setAttribute(`role`,`alert`),a.append(n(`p`,void 0,`${e.error} The numbers below are the last that loaded.`),r(`Try again`,`secondary`,t.onRetry)),i.append(a)}let s=e.query.sprint===null?null:e.sprints.find(t=>t.id===e.query.sprint)??null;i.append(ge(o,s));let c=n(`div`,`panels`),l=Te(o,a);c.append(...l,xe(o,t)),i.append(c,Ce(o),we(o)),i.append(n(`p`,`analytics-note`,`Canceled in this range: ${o.canceled}. Canceled cards are left out of every other number.`))}return a.length>0&&typeof ResizeObserver<`u`&&(o=new ResizeObserver(()=>{s===null&&(s=setTimeout(()=>{s=null;for(let e of a)e.redraw()},120))}),o.observe(i)),{element:i,dispose:()=>{o?.disconnect(),s!==null&&clearTimeout(s)}}}var De=class extends Error{status;code;constructor(e,t,n){super(n),this.status=e,this.code=t}};function Oe(e,t=()=>``){async function n(t,n,r){let i={},a=e();a&&(i.authorization=`Bearer ${a}`),t!==`GET`&&(i[`content-type`]=`application/json`);let o;try{o=await fetch(n,{method:t,headers:i,body:r===void 0?void 0:JSON.stringify(r)})}catch{throw new De(0,`server_unreachable`,`The board server has stopped. Run kanbo serve to open it again.`)}let s=await o.text();if(!o.ok){let e=ke(s);throw new De(o.status,e?.code??`unknown`,e?.message??`${o.status} ${o.statusText}`)}return JSON.parse(s)}let r=e=>`${t()}${e}`,i=e=>r(`/issues/${encodeURIComponent(e)}`);return{projects:async()=>await n(`GET`,`/projects`),workspace:async()=>await n(`GET`,r(`/issues/workspace`)),version:async()=>(await n(`GET`,r(`/issues/version`))).seq,statuses:async()=>await n(`GET`,r(`/issues/statuses`)),cards:async()=>await n(`GET`,r(`/issues`)),createCard:async e=>await n(`POST`,r(`/issues`),e),moveCard:async(e,t)=>await n(`PATCH`,`${i(e)}/status/${encodeURIComponent(t)}`),bulkUpdate:async(e,t)=>await n(`PATCH`,r(`/issues/bulk`),{issueIds:e,update:t}),metrics:async e=>{let t=new URLSearchParams;for(let[n,r]of Object.entries(e))r!==void 0&&t.set(n,String(r));return await n(`GET`,r(`/issues/metrics${t.size>0?`?${t}`:``}`))},sprints:async e=>await n(`GET`,r(`/issues/sprints?workspaceId=${encodeURIComponent(e)}`)),comments:async e=>await n(`GET`,`${i(e)}/comments`),addComment:async(e,t)=>await n(`POST`,`${i(e)}/comments`,{content:t}),activity:async e=>await n(`GET`,`${i(e)}/activity`),runs:async e=>await n(`GET`,`${i(e)}/runs`),fieldChanges:async e=>await n(`GET`,`${i(e)}/field-changes`),approve:async(e,t)=>await n(`POST`,`${i(e)}/approve`,{comment:t}),returnCard:async(e,t)=>await n(`POST`,`${i(e)}/return`,{comment:t})}}function ke(e){try{return JSON.parse(e)}catch{return null}}async function Ae(e,t,n,r){if(t.length===0)return null;let i=await e.bulkUpdate(t,n),a=i.unmetRules??[];if(a.length===0)return null;let o=a.map(e=>`${e.issueId} (${e.unmet.map(e=>e.detail).join(`; `)})`).join(`; `),s=r.column?`in ${r.column}`:`updated`;return`${i.updated} ${i.updated===1?`card is`:`cards are`} ${s}. Short of its rules: ${o}.`}function C(e){return e.title===e.id?je(e.description)??e.title:e.title}function je(e){for(let t of(e??``).split(`
|
|
2
|
+
`)){let e=Me(t);if(e)return e.length>120?`${e.slice(0,119).trimEnd()}…`:e}return null}function Me(e){return e.replace(/^\s*(?:>\s*)+/,``).replace(/^\s*#{1,6}\s+/,``).replace(/^\s*(?:[-*+]|\d+[.)])\s+(?:\[[ x]\]\s+)?/i,``).replace(/!\[([^\]]*)\]\([^)]*\)/g,`$1`).replace(/\[([^\]]*)\]\([^)]*\)/g,`$1`).replace(/<[^>]+>/g,``).replace(/[*_~`]/g,``).replace(/\s+/g,` `).trim()}function w(e,t={}){let n=document.createElementNS(`http://www.w3.org/2000/svg`,e);for(let[e,r]of Object.entries(t))n.setAttribute(e,String(r));return n}function T(e,...t){let n=w(`svg`,{viewBox:`0 0 16 16`,width:16,height:16,fill:`none`,"aria-hidden":`true`,focusable:`false`});return n.setAttribute(`class`,`icon ${e}`),n.append(...t),n}function Ne(e,t={}){return w(`circle`,{cx:8,cy:8,r:6,stroke:`currentColor`,"stroke-width":e,...t})}function E(e){let t=e??`unstarted`,n=T(`status-icon`);switch(n.dataset.category=t,t){case`triage`:n.append(Ne(2));break;case`backlog`:n.append(Ne(1.5,{"stroke-dasharray":`2 2.2`}));break;case`started`:n.append(Ne(1.5),w(`path`,{d:`M8 4.5a3.5 3.5 0 0 1 0 7z`,fill:`currentColor`}));break;case`completed`:n.append(w(`circle`,{cx:8,cy:8,r:6.75,fill:`currentColor`}));break;case`canceled`:n.append(Ne(1.5),w(`path`,{d:`M5.5 8h5`,stroke:`currentColor`,"stroke-width":1.5,"stroke-linecap":`round`}));break;default:n.append(Ne(1.5))}return n}let Pe={none:0,low:1,medium:2,high:3,urgent:4};function Fe(e){let t=T(`priority-icon`);t.dataset.priority=e;let n=Pe[e];if(n===0)return t.append(w(`path`,{d:`M3 8h10`,stroke:`currentColor`,"stroke-width":1.5,"stroke-linecap":`round`})),t;for(let e=0;e<n;e++){let n=4+2*e;t.append(w(`rect`,{x:1.75+e*3.5,y:12-n,width:2,height:n,rx:.5,fill:`currentColor`}))}return t}function Ie(){return T(`clock-icon`,w(`circle`,{cx:8,cy:8,r:6,stroke:`currentColor`,"stroke-width":1.5}),w(`path`,{d:`M8 4.75V8l2 1.25`,stroke:`currentColor`,"stroke-width":1.5,"stroke-linecap":`round`,"stroke-linejoin":`round`}))}function Le(){return T(`parent-icon`,w(`path`,{d:`M12 12.5v-3a2 2 0 0 0-2-2H4.5m0 0L7 5m-2.5 2.5L7 10`,stroke:`currentColor`,"stroke-width":1.5,"stroke-linecap":`round`,"stroke-linejoin":`round`}))}function Re(){return T(`lock-icon`,w(`rect`,{x:3.5,y:7,width:9,height:6.5,rx:1.5,stroke:`currentColor`,"stroke-width":1.5}),w(`path`,{d:`M5.5 7V5.5a2.5 2.5 0 0 1 5 0V7`,stroke:`currentColor`,"stroke-width":1.5}))}function ze(){return T(`chevron-icon`,w(`path`,{d:`M4.5 6.5 8 10l3.5-3.5`,stroke:`currentColor`,"stroke-width":1.5,"stroke-linecap":`round`,"stroke-linejoin":`round`}))}function Be(){return T(`check-icon`,w(`path`,{d:`m3.5 8.5 3 3 6-6.5`,stroke:`currentColor`,"stroke-width":1.75,"stroke-linecap":`round`,"stroke-linejoin":`round`}))}function Ve(){return T(`plus-icon`,w(`path`,{d:`M8 3.5v9M3.5 8h9`,stroke:`currentColor`,"stroke-width":1.5,"stroke-linecap":`round`}))}function He(){return T(`close-icon`,w(`path`,{d:`m4 4 8 8M12 4l-8 8`,stroke:`currentColor`,"stroke-width":1.5,"stroke-linecap":`round`}))}function Ue(){return T(`search-icon`,w(`circle`,{cx:7,cy:7,r:4.25,stroke:`currentColor`,"stroke-width":1.5}),w(`path`,{d:`m10.25 10.25 3 3`,stroke:`currentColor`,"stroke-width":1.5,"stroke-linecap":`round`}))}function We(){return T(`filter-icon`,w(`path`,{d:`M2.5 4h11M4.5 8h7M6.5 12h3`,stroke:`currentColor`,"stroke-width":1.5,"stroke-linecap":`round`}))}function Ge(){return T(`display-icon`,w(`path`,{d:`M2.5 5h6M11.5 5h2M2.5 11h2M7.5 11h6`,stroke:`currentColor`,"stroke-width":1.5,"stroke-linecap":`round`}),w(`circle`,{cx:10,cy:5,r:1.5,stroke:`currentColor`,"stroke-width":1.5}),w(`circle`,{cx:6,cy:11,r:1.5,stroke:`currentColor`,"stroke-width":1.5}))}function Ke(){return T(`board-icon`,w(`rect`,{x:2.5,y:3,width:3.25,height:10,rx:1,stroke:`currentColor`,"stroke-width":1.5}),w(`rect`,{x:8.25,y:3,width:3.25,height:6.5,rx:1,stroke:`currentColor`,"stroke-width":1.5}))}function qe(){return T(`list-icon`,w(`path`,{d:`M5.5 4h8M5.5 8h8M5.5 12h8M2.5 4h.01M2.5 8h.01M2.5 12h.01`,stroke:`currentColor`,"stroke-width":1.75,"stroke-linecap":`round`}))}function Je(){return T(`chart-icon`,w(`path`,{d:`M3.5 13V8.5M8 13V3.5M12.5 13V6`,stroke:`currentColor`,"stroke-width":2,"stroke-linecap":`round`}))}let Ye={text:``,worker:null,waiting:!1,running:!1,priorities:[],labels:[]},Xe=[`urgent`,`high`,`medium`,`low`,`none`];function Ze(e){return e.activeRun?.state===`running`&&e.activeRun.agentName?{key:`agent:${e.activeRun.agentName}`,label:e.activeRun.agentName}:e.delegateAgentId?{key:`agent:${e.delegateAgentId}`,label:e.delegateAgentId}:e.assigneeKind===`user`?{key:`user`,label:`You`}:e.assigneeKind===`agent`&&e.assigneeId?{key:`agent:${e.assigneeId}`,label:e.assigneeId}:null}function Qe(e,t){let n=t.text.trim().toLowerCase();if(n&&![e.id,e.title,e.description,e.statusLine,...e.labels].some(e=>e?.toLowerCase().includes(n)))return!1;if(t.worker!==null){let n=Ze(e);if(t.worker===`nobody`?n!==null:n?.key!==t.worker)return!1}return!(t.waiting&&e.waitingFor!==`human`||t.running&&e.activeRun?.state!==`running`||t.priorities.length>0&&!t.priorities.includes(e.priority)||t.labels.length>0&&!e.labels.some(e=>t.labels.includes(e)))}function $e(e){let t=/* @__PURE__ */ new Map,n=/* @__PURE__ */ new Set;for(let r of e){let e=Ze(r);e&&t.set(e.key,e.label);for(let e of r.labels)n.add(e)}return{workers:[...t].map(([e,t])=>({key:e,label:t})).sort((e,t)=>e.label.localeCompare(t.label)),labels:[...n].sort((e,t)=>e.localeCompare(t))}}function et(e){return e.text.trim()!==``||e.worker!==null||e.waiting||e.running||e.priorities.length>0||e.labels.length>0}function tt(e){return e?e.split(`,`).filter(e=>e!==``):[]}function nt(e){let t=new URLSearchParams(e);return{text:t.get(`q`)??``,worker:t.get(`who`)||null,waiting:t.get(`waiting`)===`1`,running:t.get(`running`)===`1`,priorities:tt(t.get(`priority`)).filter(e=>Xe.includes(e)),labels:tt(t.get(`label`))}}function rt(e,t){let n=new URLSearchParams(t),r=(e,t)=>{t?n.set(e,t):n.delete(e)};r(`q`,e.text.trim()===``?null:e.text),r(`who`,e.worker),r(`waiting`,e.waiting?`1`:null),r(`running`,e.running?`1`:null),r(`priority`,e.priorities.join(`,`)||null),r(`label`,e.labels.join(`,`)||null);let i=n.toString();return i?`?${i}`:``}let it=[`blue`,`emerald`,`amber`,`rose`,`violet`,`cyan`,`slate`];function at(e){let t=5381;for(let n=0;n<e.length;n++)t=(t<<5)+t+e.charCodeAt(n)|0;return it[Math.abs(t)%it.length]}let ot={urgent:`Urgent`,high:`High`,medium:`Medium`,low:`Low`,none:`None`};function st(e=`Waiting for you`,t=!1){let r=n(`span`,t?`waiting-pill waiting-pill--compact`:`waiting-pill`);return r.append(Ie(),e),r}function ct(){let e=n(`span`,`run-dot`);return e.setAttribute(`aria-hidden`,`true`),e}function D(e){return e.activeRun?.state===`running`}function lt(e,t){let r=Ze(e);if(!r&&!t)return null;let i=r?.label??`Agent`,a=n(`span`,`avatar`,i.charAt(0).toUpperCase());a.dataset.kind=r?.key===`user`?`user`:`agent`;let o=t?`${r?i:`An agent`} is running`:i;return a.title=t&&e.activeRun?.agentName?`Running · ${e.activeRun.agentName}`:o,a.setAttribute(`role`,`img`),a.setAttribute(`aria-label`,a.title),t&&(a.dataset.running=``,a.append(ct())),a}function ut(e){let t=n(`span`,`label`,e);return t.dataset.tone=at(e),t}function dt(e,t=2){let r=e.slice(0,t).map(ut);if(e.length>t){let i=n(`span`,`label-more`,`+${e.length-t}`);i.title=e.slice(t).join(`, `),r.push(i)}return r}function ft(e){if(e===`none`)return null;let t=n(`span`,`priority`);return t.dataset.priority=e,t.append(Fe(e),n(`span`,`priority-word`,ot[e])),t}function pt(e){return{short:`${e.done}/${e.total} done`,words:`${e.done} of ${e.total} sub-tasks done`}}function mt(e){let{short:t,words:r}=pt(e),i=n(`div`,`progress`),a=n(`progress`,`progress-bar`);a.max=e.total,a.value=e.done,a.setAttribute(`aria-label`,r);let o=n(`span`,`progress-text`,t);return o.title=r,i.append(a,o),i}function ht(e,t){let r=n(`li`),i=n(`button`,`subtask-row`);i.type=`button`,i.dataset.subtaskId=e.card.id,i.toggleAttribute(`data-dim`,e.faded);let a=C(e.card);i.title=`${e.card.id} · ${a}`,i.append(E(e.category),n(`span`,`card-key`,e.card.id),n(`span`,`row-title`,a));let o=n(`span`,`row-end`);return e.attention&&o.append(st(`Waiting`,!0)),D(e.card)&&o.append(ct()),e.own&&o.append(n(`span`,`row-count`,`${e.own.done}/${e.own.total}`)),i.append(o),i.addEventListener(`click`,n=>{n.stopPropagation(),t(e.card.id)}),r.append(i),r}function gt(e){let t=n(`input`,`select-box`);return t.type=`checkbox`,t.setAttribute(`aria-label`,`Select ${e}`),t}function _t(e,t){return e.waitingFor===`human`?`waiting`:D(e)?`running`:t===`completed`?`done`:t===`canceled`?`quiet`:`idle`}function vt(e,t){if(!e.parentIssueId||e.parentIssueId===e.id)return null;let r=t.parent,i=n(r?`button`:`span`,`subtask-strip`);if(i.append(Le(),n(`span`,`strip-label`,`Sub-task of`),n(`span`,`card-key`,e.parentIssueId)),r){let e=C(r),a=i;a.type=`button`,i.append(n(`span`,`strip-title`,e)),i.title=`Sub-task of ${r.id} · ${e}`,i.addEventListener(`click`,e=>{e.stopPropagation(),t.onOpenCard(r.id)})}return i}function yt(e,t,r){let i=n(`div`,`subtask-block`),a=n(`ul`,`subtask-list`);if(a.append(...e.rows.map(e=>ht(e,t.onOpenCard))),i.append(a),e.more>0){let t=n(`button`,`subtask-more`,`+${e.more} more`);t.type=`button`,t.addEventListener(`click`,r),i.append(t)}return e.summary&&i.append(mt(e.summary)),i}function bt(e,t,r,i){let a=n(`article`,`card`);if(a.draggable=!0,a.dataset.cardId=e.id,a.dataset.state=_t(e,t),i){let t=vt(e,i);t&&(a.dataset.subtask=``,a.append(t))}let o=n(`div`,`card-meta`);o.append(gt(e.id),n(`span`,`card-key`,e.id),n(`span`,`spacer`));let s=lt(e,D(e)||i?.runsBelow===!0);s&&o.append(s),a.append(o);let c=n(`button`,`card-title`,C(e));c.type=`button`,c.addEventListener(`click`,()=>r(e)),a.append(c);let l=e.statusLine?.trim()??``,u=e.waitingFor===`human`,d=e.attemptCount>1,f=i?.waitsBelow===!0;if(l||u||f||d){let r=n(`div`,`card-status`);if(l){let e=n(`p`,`status-line`,l);e.title=l,e.dataset.category=t??`unstarted`,r.append(e)}if(u&&r.append(st()),f&&r.append(st(`Sub-task waiting for you`)),d){let t=n(`span`,`attempt-chip`,`×${e.attemptCount}`);t.title=`Attempt ${e.attemptCount}`,r.append(t)}a.append(r)}let p=ft(e.priority);if(p||e.labels.length>0){let t=n(`div`,`card-footer`);p&&t.append(p),t.append(...dt(e.labels)),a.append(t)}return i?.block?a.append(yt(i.block,i,()=>r(e))):i?.summary&&a.append(mt(i.summary)),a}let xt={subtasks:`inside`,view:`board`,range:12,sprint:null};function St(e){let t=new URLSearchParams(e),n=t.get(`view`),r=Number(t.get(`range`));return{subtasks:t.get(`subtasks`)===`cards`?`cards`:`inside`,view:n===`list`||n===`analytics`?n:`board`,range:r===4||r===26?r:12,sprint:t.get(`sprint`)||null}}function Ct(e,t){let n=new URLSearchParams(t);e.subtasks===`cards`?n.set(`subtasks`,`cards`):n.delete(`subtasks`),e.view===`board`?n.delete(`view`):n.set(`view`,e.view),e.view===`analytics`&&e.range!==12?n.set(`range`,String(e.range)):n.delete(`range`),e.view===`analytics`&&e.sprint!==null?n.set(`sprint`,e.sprint):n.delete(`sprint`);let r=n.toString();return r?`?${r}`:``}function wt(e){return new Map(e.map(e=>[e.id,{statusId:e.statusId,waiting:e.waitingFor===`human`}]))}function Tt(e,t){if(e===null)return null;let n=e.get(t.id);return n?n.statusId===t.statusId?null:`moved`:`new`}function Et(e,t){return e!==null&&t.waitingFor===`human`&&e.get(t.id)?.waiting!==!0}function Dt(e,t,n){let r=e?.wipLimit??null;return r===null?{text:String(t),full:!1}:{text:`${n}/${r}`,full:n>=r}}let Ot={checklist_complete:`every checklist item checked`,pull_request_linked:`a pull request linked`,ci_green:`CI green`,approved:`a person's approval`};function kt(e,t){let n=[];if(e.allowedFrom!==null){let r=e.allowedFrom.map(e=>t.find(t=>t.id===e)?.name??e);n.push(r.length===0?`Only a person puts a card here`:`Accepts cards only from ${r.join(`, `)}`)}return e.wipLimit!==null&&n.push(`Limit: ${e.wipLimit} ${e.wipLimit===1?`card`:`cards`}`),e.entryRules.length>0&&n.push(`A card needs: ${e.entryRules.map(e=>Ot[e]??e).join(`; `)}`),n.length===0?null:n.join(`
|
|
3
|
+
`)}function At(e,t=()=>!0){let n=/* @__PURE__ */ new Map;for(let r of e)r.statusId!==null&&t(r)&&n.set(r.statusId,(n.get(r.statusId)??0)+1);return n}function jt(e,t,n){let r=e=>{let n=t.findIndex(t=>t.id===e.statusId);return n===-1?t.length:n};return e.filter(e=>e.parentIssueId===n&&e.id!==n).sort((e,t)=>r(e)-r(t)||e.order-t.order)}function Mt(e,t,n){let r=e=>t.find(t=>t.id===e.statusId)?.category,i=jt(e,t,n).filter(e=>r(e)!==`canceled`);return i.length===0?null:{total:i.length,done:i.filter(e=>r(e)===`completed`).length}}function Nt(e,t){return!t.parentIssueId||t.parentIssueId===t.id?null:e.find(e=>e.id===t.parentIssueId)??null}function Pt(e,t){let n=/* @__PURE__ */ new Set([t.id]),r=Nt(e,t);if(r===null)return!1;for(;r!==null;){if(n.has(r.id))return!1;n.add(r.id),r=Nt(e,r)}return!0}function Ft(e,t){return t===`cards`?[...e]:e.filter(t=>!Pt(e,t))}function It(e,t,n){let r=jt(e,t,n);return{rows:r.slice(0,5),more:Math.max(0,r.length-5)}}function Lt(e,t){let n=[],r=/* @__PURE__ */ new Set([t]),i=[t];for(;i.length>0;){let t=i.shift();for(let a of e)a.parentIssueId===t&&!r.has(a.id)&&(r.add(a.id),n.push(a),i.push(a.id))}return n}function Rt(e,t){return Lt(e,t).some(e=>e.waitingFor===`human`)}function zt(e,t){return Lt(e,t).some(e=>e.activeRun?.state===`running`)}function Bt(e,t,n){if(t===`cards`){let t=new Set(e.filter(n).map(e=>e.id));return{drawn:t,faded:/* @__PURE__ */ new Set,count:t.size}}let r=/* @__PURE__ */ new Set,i=/* @__PURE__ */ new Set,a=0;for(let t of Ft(e,`inside`)){let o=Lt(e,t.id),s=new Set(o.filter(n).map(e=>e.id));if(n(t)||s.size!==0){r.add(t.id),a+=1+s.size;for(let n of e.filter(e=>e.parentIssueId===t.id&&e.id!==t.id))s.has(n.id)||Lt(e,n.id).some(e=>s.has(e.id))||i.add(n.id)}}return{drawn:r,faded:i,count:a}}function Vt(e,t,n,r){return{card:n,category:t.find(e=>e.id===n.statusId)?.category??null,own:Mt(e,t,n.id),faded:r.has(n.id),attention:n.waitingFor===`human`||Rt(e,n.id)}}function Ht(e,t,n){return jt(e,t,n).map(n=>Vt(e,t,n,/* @__PURE__ */ new Set))}function Ut(e,t,n,r){let{rows:i,more:a}=It(e,t,n);return i.length===0?null:{rows:i.map(n=>Vt(e,t,n,r)),more:a,summary:Mt(e,t,n)}}function Wt(e,t,n,r){return e.flatMap(e=>[{card:e,depth:0},...r===`inside`?jt(t,n,e.id).map(e=>({card:e,depth:1})):[]])}function Gt(e,t){let n=Math.max(0,t-e);if(n<60)return`now`;let[r,i]=[[31536e3,`y`],[2592e3,`mo`],[86400,`d`],[3600,`h`],[60,`m`]].find(([e])=>n>=e);return`${Math.floor(n/r)}${i}`}function Kt(e){return`kanbo:list-collapsed:${e}`}function qt(e,t){try{let n=JSON.parse(e.getItem(Kt(t))??`[]`);return new Set(Array.isArray(n)?n.filter(e=>typeof e==`string`):[])}catch{return/* @__PURE__ */ new Set}}function Jt(e,t,n){e.setItem(Kt(t),JSON.stringify([...n]))}function Yt(e,t){let{card:r}=e,i=n(`div`,`list-row`);i.dataset.cardId=r.id,i.dataset.depth=String(e.depth),i.toggleAttribute(`data-dim`,t.faded.has(r.id));let a=t.statuses.find(e=>e.id===r.statusId)?.category??null;i.dataset.state=r.waitingFor===`human`?`waiting`:D(r)?`running`:a===`completed`?`done`:a===`canceled`?`quiet`:`idle`;let o=n(`span`,`row-icons`);if(o.append(E(a),Fe(r.priority)),i.append(gt(r.id),o,n(`span`,`card-key`,r.id)),e.depth===0&&t.mode===`cards`&&r.parentIssueId&&r.parentIssueId!==r.id){let e=t.cards.find(e=>e.id===r.parentIssueId),a=n(`span`,`row-parent`);a.append(Le(),r.parentIssueId),a.title=e?`Sub-task of ${e.id} · ${C(e)}`:`Sub-task of ${r.parentIssueId}`,i.append(a)}let s=n(`button`,`list-title`,C(r));s.type=`button`,s.addEventListener(`click`,()=>t.onOpen(r.id)),i.append(s);let c=n(`span`,`row-marks`);r.waitingFor===`human`&&c.append(st()),D(r)&&c.append(ct());let l=e.depth===1&&t.mode===`inside`?Mt(t.cards,t.statuses,r.id):null;l&&c.append(n(`span`,`row-count`,`${l.done}/${l.total}`)),i.append(c);let u=n(`span`,`row-meta`);u.append(...dt(r.labels));let d=lt(r,D(r));d&&u.append(d);let f=n(`span`,`row-age`,Gt(r.createdAt,t.now));return f.title=(/* @__PURE__ */ new Date(r.createdAt*1e3)).toLocaleString(),u.append(f),i.append(u),i}function Xt(e){let t=n(`div`,`list`);for(let r of e.groups){let i=n(`section`,`list-group`);i.setAttribute(`aria-label`,r.name);let a=r.status,o=e.collapsed.has(r.id),s=n(`div`,`list-group-head`),c=n(`button`,`group-toggle`);c.type=`button`,c.setAttribute(`aria-expanded`,String(!o)),c.setAttribute(`aria-label`,`${r.name}, ${o?`folded`:`open`}`),c.addEventListener(`click`,()=>e.onToggleGroup(r.id)),c.append(ze());let l=Dt(a,a?e.tally.shown.get(a.id)??0:r.cards.length,a?e.tally.total.get(a.id)??0:r.cards.length),u=n(`span`,`group-count`,l.text);u.toggleAttribute(`data-full`,l.full),s.append(c,E(a?.category??null),n(`span`,`group-name`,r.name),u);let d=a?kt(a,e.statuses):null;if(d){let e=n(`span`,`column-lock`);e.append(Re()),e.title=d,e.setAttribute(`role`,`img`),e.setAttribute(`aria-label`,d.replaceAll(`
|
|
4
|
+
`,`. `)),s.append(e)}if(i.append(s),!o){let t=Wt(r.cards,e.cards,e.statuses,e.mode);t.length===0?i.append(n(`p`,`list-empty`,`No cards`)):i.append(...t.map(t=>Yt(t,e)))}t.append(i)}return t}function Zt(e,t){if(t.modifier)return null;if(t.typing)return e===`Escape`&&t.dialogOpen?{type:`close-dialog`}:null;if(e===`Escape`)return t.dialogOpen?{type:`close-dialog`}:t.popoverOpen?{type:`close-popover`}:t.hasSelection?{type:`clear-selection`}:null;if(t.dialogOpen||t.popoverOpen)return null;switch(e){case`j`:case`J`:case`ArrowDown`:return{type:`move`,dy:1,extend:t.shift};case`k`:case`K`:case`ArrowUp`:return{type:`move`,dy:-1,extend:t.shift};case`ArrowLeft`:return{type:`column`,dx:-1};case`ArrowRight`:return{type:`column`,dx:1};case`Enter`:case` `:return{type:`open`};case`x`:case`X`:return{type:`toggle`};case`/`:return{type:`search`};default:return null}}function Qt(e,t,n,r){let i=e.map((e,t)=>({ids:e,index:t})).filter(e=>e.ids.length>0);if(i.length===0)return null;let a=i.find(e=>e.ids.includes(t??``));if(!a)return i[0].ids[0];let o=a.ids.indexOf(t);if(r!==0)return a.ids[Math.min(a.ids.length-1,Math.max(0,o+r))];let s=i[i.indexOf(a)+Math.sign(n)];return s?s.ids[Math.min(o,s.ids.length-1)]:t}function $t(e){return e instanceof HTMLElement?e.isContentEditable||e.tagName===`TEXTAREA`||e.tagName===`SELECT`?!0:e instanceof HTMLInputElement&&![`checkbox`,`radio`,`button`,`submit`].includes(e.type):!1}function en(e){let t=(e,t)=>[...e.querySelectorAll(t)].map(e=>e.dataset.cardId).filter(Boolean);return e.querySelector(`.list`)?[t(e,`.list-row`)]:[...e.querySelectorAll(`.column-cards`)].map(e=>t(e,`.card`))}function tn(e,t){let n=Zt(e.key,{shift:e.shiftKey,modifier:e.metaKey||e.ctrlKey||e.altKey,...t.state()});if(!n)return!1;let r=t.focusedId();switch(n.type){case`move`:case`column`:{let e=n.type===`move`?Qt(t.layout(),r,0,n.dy):Qt(t.layout(),r,n.dx,0);if(!e)return!1;n.type===`move`&&n.extend&&r&&e!==r&&t.extend(r,e),t.focus(e);break}case`open`:if(!r||e.target instanceof HTMLElement&&e.target.closest(`button, a, input, select, textarea, summary`)&&!e.target.closest(`.card-title, .list-title`))return!1;t.open(r);break;case`toggle`:if(!r)return!1;t.toggle(r);break;case`search`:t.search();break;case`close-dialog`:t.closeDialog();break;case`close-popover`:t.closePopover();break;case`clear-selection`:t.clearSelection()}return e.preventDefault(),!0}let O=null;function nn(){return O?.isOpen()??!1}function rn(){return O?.isOpen()?(O.close(),!0):!1}function an(e,t,r,i,a=`start`,o=`bottom`){let s=null;t.setAttribute(`aria-haspopup`,`dialog`),t.setAttribute(`aria-expanded`,`false`);let c=e=>{s&&!s.contains(e.target)&&!t.contains(e.target)&&d(!1)},l=e=>{e.key===`Escape`&&(e.stopPropagation(),d(!0))};function u(){s||(O&&O!==f&&O.close(),s=n(`div`,`popover`),s.setAttribute(`role`,`dialog`),s.setAttribute(`aria-label`,r),s.dataset.align=a,s.dataset.side=o,s.append(...i().children),e.append(s),t.setAttribute(`aria-expanded`,`true`),O=f,document.addEventListener(`pointerdown`,c,!0),document.addEventListener(`keydown`,l,!0),s.querySelector(`input, button`)?.focus())}function d(e){s&&(s.remove(),s=null,t.setAttribute(`aria-expanded`,`false`),document.removeEventListener(`pointerdown`,c,!0),document.removeEventListener(`keydown`,l,!0),O===f&&(O=null),e&&t.focus())}let f={isOpen:()=>s!==null,open:u,close:()=>d(!0),refresh:()=>{if(!s)return;let e=document.activeElement?.closest(`[data-key]`)?.dataset.key;s.replaceChildren(...i().children),e!==void 0&&s.querySelector(`[data-key="${CSS.escape(e)}"]`)?.focus()}};return t.addEventListener(`click`,()=>s?d(!0):u()),f}let on={ids:/* @__PURE__ */ new Set,anchor:null};function sn(e,t){let n=new Set(e.ids);return n.delete(t)||n.add(t),{ids:n,anchor:t}}function cn(e,t,n){let r=t.indexOf(n),i=e.anchor===null?-1:t.indexOf(e.anchor),a=new Set(e.ids);if(r===-1||i===-1)return a.add(n),{ids:a,anchor:n};for(let e of t.slice(Math.min(i,r),Math.max(i,r)+1))a.add(e);return{ids:a,anchor:e.anchor}}function ln(e,t,n){let r=new Set(e.ids);return r.add(t),r.add(n),{ids:r,anchor:e.anchor??t}}function un(){return on}function dn(e,t){let n=[...e.ids].filter(e=>t.has(e));return n.length===e.ids.size&&(e.anchor===null||t.has(e.anchor))?e:{ids:new Set(n),anchor:e.anchor!==null&&t.has(e.anchor)?e.anchor:null}}let fn=[`urgent`,`high`,`medium`,`low`,`none`];function pn(e){let t={count:0,statuses:[]},r=n(`div`,`selection-bar`);r.setAttribute(`role`,`toolbar`),r.setAttribute(`aria-label`,`Selected cards`),r.hidden=!0;let i=n(`span`,`selection-count`),a=n(`span`,`selection-summary`);a.append(Be(),i);let o=e=>{let t=n(`span`,`anchor`),r=n(`button`,`tool-button`);return r.type=`button`,r.append(e,ze()),t.append(r),{anchor:t,trigger:r}},s=(e,...t)=>{let r=n(`button`,`menu-item`);return r.type=`button`,r.append(...t),r.addEventListener(`click`,e),r},c=o(`Status`),l=an(c.anchor,c.trigger,`Move to column`,()=>{let r=n(`div`,`menu`);return r.append(...t.statuses.map(t=>s(()=>{l.close(),e.onMove(t.id)},E(t.category),t.name))),r},`start`,`top`),u=o(`Priority`),d=an(u.anchor,u.trigger,`Set priority`,()=>{let t=n(`div`,`menu`);return t.append(...fn.map(t=>s(()=>{d.close(),e.onPriority(t)},Fe(t),ot[t]))),t},`start`,`top`),f=n(`button`,`icon-button selection-clear`);return f.type=`button`,f.setAttribute(`aria-label`,`Clear selection`),f.title=`Clear selection (Esc)`,f.append(He()),f.addEventListener(`click`,e.onClear),r.append(a,c.anchor,u.anchor,n(`span`,`divider`),f),{element:r,update:e=>{t=e,i.textContent=`${e.count} selected`,r.hidden=e.count===0,e.count===0&&(l.close(),d.close()),l.refresh()}}}function mn(e,t){let n=new Set(t.map(e=>e.statusId)),r=e.filter(e=>e.category!==`canceled`||n.has(e.id)).map(e=>({id:e.id,name:e.name,status:e,cards:[]})),i=new Map(r.map(e=>[e.id,e])),a=new Set(e.map(e=>e.id));for(let e of t){let t=e.statusId??``,n=i.get(t);!n&&!a.has(t)&&(n={id:t,name:e.statusId??`No status`,status:null,cards:[]},i.set(t,n),r.push(n)),n?.cards.push(e)}return r}function hn(e){let t=e.filter(e=>e.category!==`canceled`);return t.find(e=>/^to ?do$/i.test(e.name.trim()))??t.find(e=>e.category===`unstarted`)??t[0]??null}function gn(e){switch(e){case`assignee`:return`Assignee`;case`description`:return`Description`;case`due-date`:return`Due date`;case`labels`:return`Labels`;case`metadata`:return`Metadata`;case`milestone`:return`Milestone`;case`parent`:return`Parent card`;case`priority`:return`Priority`;case`status`:return`Column`;case`status-line`:return`Status line`;case`title`:return`Title`;case`workspace`:return`Workspace`}}function _n(e,t){let n=new Map(t.map(e=>[e.id,e])),r=[];for(let t of e){if(t.kind===`comment`)continue;let e={kind:t.actor.kind,name:t.actor.displayName,label:t.actor.label},i={id:t.id,actor:e,field:null,from:null,to:null,text:null,at:t.createdAt},a=t.fieldChange;if(t.kind===`created`)r.push({...i,verb:`created the card`});else if(!a)r.push({...i,verb:`changed the card`});else if(a.action===`added-description`||a.action===`updated-description`||a.action===`cleared-description`){let e=n.get(t.id),o=a.action===`added-description`?`added the description`:a.action===`cleared-description`?`cleared the description`:`updated the description`;r.push({...i,verb:o,text:e?{before:e.fromValue,after:e.toValue}:null})}else if(a.field===`metadata`||a.field===null)r.push({...i,verb:`changed metadata`});else{let e=a.field===`status`?`moved it`:a.action===`renamed-issue`?`renamed it`:`changed`;r.push({...i,verb:e,field:gn(a.field),from:vn(a.fromValue),to:vn(a.toValue)})}}return[...r].sort((e,t)=>t.at-e.at)}function vn(e){if(!e)return`nothing`;if(e.kind===`text`)return e.text;if(e.kind===`date`)return(/* @__PURE__ */ new Date(e.timestamp*1e3)).toLocaleDateString();if(e.token.startsWith(`priority-`)){let t=e.token.slice(9);return`${t.charAt(0).toUpperCase()}${t.slice(1)}`}return e.token===`current-user`?`you`:e.token.replaceAll(`-`,` `)}function yn(e,t){return e.getFullYear()===t.getFullYear()&&e.getMonth()===t.getMonth()&&e.getDate()===t.getDate()}function bn(e,t){return e.toLocaleDateString(void 0,{day:`numeric`,month:`short`,year:e.getFullYear()===t.getFullYear()?void 0:`numeric`})}function xn(e,t){return yn(e,t)?`Today`:yn(e,new Date(t.getFullYear(),t.getMonth(),t.getDate()-1))?`Yesterday`:bn(e,t)}function Sn(e,t){let n=[];for(let r of e){let e=xn(/* @__PURE__ */ new Date(r.at*1e3),t),i=n.at(-1);i&&i.day===e?i.entries.push(r):n.push({day:e,entries:[r]})}return n}function Cn(e,t){let n=/* @__PURE__ */ new Date(e*1e3);if(!yn(n,t))return Tn(n);let r=Math.floor(t.getTime()/1e3)-e;return r<60?`just now`:r<3600?`${Math.floor(r/60)} min ago`:`${Math.floor(r/3600)} h ago`}function wn(e,t,{withClock:n=!1}={}){let r=/* @__PURE__ */ new Date(e*1e3);return yn(r,t)?Cn(e,t):n?`${xn(r,t)} ${Tn(r)}`:xn(r,t)}function Tn(e){return e.toLocaleTimeString(void 0,{hour:`2-digit`,minute:`2-digit`})}let En=[{tab:`comments`,label:`Comments`},{tab:`history`,label:`History`},{tab:`runs`,label:`Runs`}];function Dn(e,t){return e.querySelector(`.panel-head .card-key`)?.textContent===t?e.querySelector(`.panel-scroll`)?.scrollTop??0:0}function On(e,t,r){let{card:i,status:a}=e,o=n(`div`,`panel`);o.setAttribute(`role`,`dialog`),o.setAttribute(`aria-modal`,`true`);let s=`panel-title`;o.setAttribute(`aria-labelledby`,s);let c=kn(e,t),l=n(`div`,`panel-scroll`),u=n(`div`,`panel-top`),d=n(`h2`,`panel-title`,C(i));d.id=s,u.append(d);let f=_n(e.activity,e.fieldChanges),p=/* @__PURE__ */ new Date;if(i.statusLine?.trim()){let e=n(`p`,`status-line`,i.statusLine.trim());e.dataset.category=a?.category??`unstarted`,u.append(e)}let m=n(`p`,`panel-notice`,r??``);m.setAttribute(`role`,`alert`),m.hidden=!r,u.append(m);let h=n(`div`,`panel-main`);h.append(Rn(`Description`,i.description?.trim()?n(`div`,`description`,i.description):n(`p`,`empty`,`No description.`))),e.subtasks.length>0&&h.append(Pn(e,t));let g=[...Bn(e.comments,t,p)],ee=[In(f,p)],_=[Hn(e.runs,e=>[Un(e),e.startedAt,e.state],`No runs.`,p)],v={comments:e.comments.length,history:f.length,runs:e.runs.length},y={comments:g,history:ee,runs:_};h.append(jn(e.tab,v,y,t));let b=n(`div`,`panel-side`);b.append(zn(i,t),Rn(`Details`,Nn(i,a,e.parent,e.runs,t,f,p)));let x=n(`div`,`panel-body`);return x.append(h,b),l.append(u,x),o.append(c,l),o}function kn(e,t){let{card:r,status:i}=e,a=n(`div`,`panel-head`);if(a.append(n(`span`,`card-key`,r.id)),r.parentIssueId&&r.parentIssueId!==r.id){let i=e.parent,o=n(i?`button`:`span`,`breadcrumb`);if(o.append(n(`span`,`crumb-label`,`Sub-task of`),Le()),i){let e=C(i);o.append(n(`span`,`crumb-title`,e)),o.title=`Sub-task of ${i.id} · ${e}`;let r=o;r.type=`button`,o.addEventListener(`click`,()=>t.openCard(i.id))}else o.append(n(`span`,`card-key`,r.parentIssueId));a.append(o)}let o=n(`span`,`column-pill`);if(o.append(E(i?.category??null),i?i.name:`No column`),a.append(o),r.waitingFor===`human`&&a.append(st()),D(r)){let e=n(`span`,`run-state`);e.append(ct(),r.activeRun?.agentName?`Running · ${r.activeRun.agentName}`:`Running`),a.append(e)}if(a.append(n(`span`,`spacer`)),e.summary){let t=n(`span`,`done-pill`,pt(e.summary).short);t.title=pt(e.summary).words,a.append(t)}e.siblings.length>1&&a.append(An(e,t));let s=n(`button`,`icon-button panel-close`);return s.type=`button`,s.append(He()),s.setAttribute(`aria-label`,`Close`),s.title=`Close (Esc)`,s.addEventListener(`click`,t.close),a.append(s),a}function An(e,t){let r=n(`div`,`sibling-switch`);r.setAttribute(`role`,`group`),r.setAttribute(`aria-label`,`Sub-tasks of the same card`);let i=e.siblings.findIndex(t=>t.id===e.card.id),a=(e,r,i)=>{let a=n(`button`,`icon-button sibling-step`,r);return a.type=`button`,a.setAttribute(`aria-label`,e),a.disabled=i===void 0,i&&(a.title=`${e}: ${i.id}`,a.addEventListener(`click`,()=>t.openCard(i.id))),a},o=n(`span`,`sibling-position`,`${i+1}/${e.siblings.length}`);return r.append(a(`Previous sub-task`,`‹`,e.siblings[i-1]),o,a(`Next sub-task`,`›`,e.siblings[i+1])),r}function jn(e,t,r,i){let a=n(`div`,`tabs-wrap`),o=n(`div`,`tabs`);o.setAttribute(`role`,`tablist`);let s=[],c=/* @__PURE__ */ new Map,l=/* @__PURE__ */ new Map,u=e=>{for(let[t,n]of c)n.setAttribute(`aria-selected`,String(t===e)),n.tabIndex=t===e?0:-1,l.get(t).hidden=t!==e;i.selectTab(e)};return En.forEach(({tab:i,label:a},d)=>{let f=n(`button`,`tab`);f.type=`button`,f.id=`tab-${i}`,f.setAttribute(`role`,`tab`),f.setAttribute(`aria-selected`,String(i===e)),f.setAttribute(`aria-controls`,`tab-panel-${i}`),f.tabIndex=i===e?0:-1,f.append(a,n(`span`,`count`,String(t[i]))),f.addEventListener(`click`,()=>u(i)),f.addEventListener(`keydown`,e=>{if(e.key!==`ArrowLeft`&&e.key!==`ArrowRight`)return;e.preventDefault();let t=En[(d+(e.key===`ArrowRight`?1:En.length-1))%En.length].tab;u(t),c.get(t)?.focus()}),c.set(i,f),o.append(f);let p=n(`div`,`tab-panel`);p.id=`tab-panel-${i}`,p.setAttribute(`role`,`tabpanel`),p.setAttribute(`aria-labelledby`,f.id),p.hidden=i!==e,p.append(...r[i]),l.set(i,p),s.push(p)}),a.append(o,...s),a}function Mn(e,t){let r=/* @__PURE__ */ new Date(e*1e3),i=n(`time`,`history-time`,t);return i.dateTime=r.toISOString(),i.title=r.toLocaleString(),i}function Nn(e,t,r,i,a,o,s){let c=n(`dl`,`facts`),l=(e,...t)=>{let r=n(`dd`);r.append(...t),c.append(n(`dt`,void 0,e),r)};if(e.parentIssueId){if(r){let e=n(`button`,`link`);e.type=`button`,e.append(n(`span`,`card-key`,r.id),n(`span`,`link-title`,C(r))),e.addEventListener(`click`,()=>a.openCard(r.id)),l(`Parent`,e)}else l(`Parent`,n(`span`,`card-key`,e.parentIssueId))}let u=n(`span`,`fact-column`);u.append(E(t?.category??null),t?t.name:`No column`),l(`Column`,u);let d=o.find(e=>e.verb===`created the card`);l(`Created by`,Fn(d?{kind:d.actor.kind,name:d.actor.name,label:d.actor.label}:{kind:e.createdByKind,name:e.createdByKind===`user`?`You`:e.createdById??e.createdByKind,label:null}),` `,n(`span`,`muted`,`· ${wn(d?.at??e.createdAt,s)}`));let f=Ze(e),p=f?null:i.reduce((e,t)=>e===null||t.startedAt>e.startedAt?t:e,null);return p?l(`Worked by`,Fn({kind:`agent`,name:p.agentName,label:null}),` `,n(`span`,`muted`,`· ${p.state}`)):l(`Worked by`,f?Fn({kind:f.key===`user`?`user`:`agent`,name:f.label,label:null}):`Nobody`,...e.activeRun?.state===`running`?[` `,n(`span`,`muted`,`· running`)]:[]),l(`Priority`,ft(e.priority)??n(`span`,`muted`,`None`)),e.labels.length>0&&l(`Labels`,...dt(e.labels,e.labels.length)),c}let k=!1;function Pn(e,t){let r=n(`section`,`panel-section subtasks-section`),i=n(`div`,`subtasks-head`),a=n(`button`,`subtasks-fold`);if(a.type=`button`,a.setAttribute(`aria-expanded`,String(!k)),a.setAttribute(`aria-label`,`Sub-tasks`),a.append(ze(),n(`h3`,void 0,`Sub-tasks`)),i.append(a),e.summary){let{short:t,words:r}=pt(e.summary),a=n(`span`,`subtasks-count`,`${e.summary.done}/${e.summary.total}`);a.title=r;let o=n(`progress`,`progress-bar`);o.max=e.summary.total,o.value=e.summary.done,o.setAttribute(`aria-label`,t),i.append(a,o)}let o=n(`ul`,`subtask-list`);return o.hidden=k,o.append(...e.subtasks.map(e=>ht(e,t.openCard))),a.addEventListener(`click`,()=>{k=!k,o.hidden=k,a.setAttribute(`aria-expanded`,String(!k))}),r.append(i,o),r}function Fn(e){let t=n(`span`,`actor-chip`,e.name),r=e.label===`External`;return t.dataset.kind=r||e.kind===`provider-target`?`agent`:e.kind,r?t.title=e.label??``:e.label&&t.append(n(`small`,`actor-label`,` ${e.label}`)),t}function In(e,t){let r=Rn(`History`);if(e.length===0)return r.append(n(`p`,`empty`,`No history yet.`)),r;for(let i of Sn(e,t)){let e=n(`section`,`history-day`);e.append(n(`h4`,void 0,i.day));let a=n(`ol`,`history-list`);for(let e of i.entries)a.append(Ln(e,t));e.append(a),r.append(e)}return r}function Ln(e,t){let r=n(`li`,`history-entry`);r.dataset.kind=e.actor.label===`External`||e.actor.kind===`provider-target`?`agent`:e.actor.kind;let i=n(`span`,`history-what`);if(i.append(Fn(e.actor),` ${e.verb}`),e.field&&i.append(` `,n(`span`,`history-field`,e.field)),r.append(i,Mn(e.at,Cn(e.at,t))),e.from!==null||e.to!==null){let t=n(`span`,`history-change`);e.from!==null&&t.append(n(`del`,`value-from`,e.from)),e.to!==null&&t.append(n(`ins`,`value-to`,e.to)),r.append(t)}if(e.text){let t=n(`details`,`history-text`);t.append(n(`summary`,void 0,`Show before / after`));let i=n(`div`,`history-text-pair`);for(let[t,r,a]of[[`before`,`Before`,e.text.before],[`after`,`After`,e.text.after]]){let e=n(`p`,`history-text-block`);e.dataset.side=t,e.append(n(`b`,void 0,r),a??``),i.append(e)}t.append(i),r.append(t)}return r}function Rn(e,...t){let r=n(`section`,`panel-section`);return r.append(n(`h3`,void 0,e),...t),r}function zn(e,t){let i=n(`textarea`,`field`);i.rows=2,i.placeholder=e.waitingFor===`human`?`A note for the agent (needed to return)`:`Why it goes back (needed to return)`,i.setAttribute(`aria-label`,`Decision note`);let a=n(`p`,`hint`),o=n(`div`,`row`);e.waitingFor===`human`&&o.append(r(`Approve`,`primary`,()=>t.approve(i.value.trim()||null))),o.append(r(`Return`,`ghost`,()=>{let e=i.value.trim();if(!e){a.textContent=`Say why in the note to return the card.`,i.focus();return}t.returnCard(e)}));let s=Rn(`Decision`,i,o,a);return e.waitingFor===`human`&&(s.dataset.waiting=``),s}function Bn(e,t,r){if(e.length===0)return[Vn(t),n(`p`,`empty`,`No comments.`)];let i=n(`ul`,`entries`);for(let t of[...e].reverse()){let e=n(`li`),a=n(`div`,`entry-meta`);a.append(Fn({kind:t.author.kind,name:t.author.displayName,label:t.author.label}),Mn(t.createdAt,wn(t.createdAt,r,{withClock:!0}))),e.append(a,n(`div`,`entry-text`,t.content)),i.append(e)}return[Vn(t),i]}function Vn(e){let t=n(`div`,`comment-form`),i=n(`textarea`,`field`);return i.rows=4,i.placeholder=`Add a comment`,i.setAttribute(`aria-label`,`New comment`),t.append(i,r(`Comment`,`secondary`,()=>{let t=i.value.trim();t&&e.addComment(t)})),t}function Hn(e,t,r,i){if(e.length===0)return n(`p`,`empty`,r);let a=n(`ul`,`entries`);for(let r of e){let[e,o,s]=t(r),c=n(`li`);c.dataset.runState=s;let l=n(`div`,`entry-meta`);l.append(Mn(o,wn(o,i,{withClock:!0}))),c.append(n(`div`,`entry-text`,e),l),a.append(c)}return a}function Un(e){return[`Attempt ${e.attempt}`,e.agentName,e.state,e.branch].filter(Boolean).join(` · `)}function Wn(e=globalThis.crypto){return typeof e.randomUUID==`function`?e.randomUUID():Array.from(e.getRandomValues(/* @__PURE__ */ new Uint8Array(16)),e=>e.toString(16).padStart(2,`0`)).join(``)}function Gn(e){let t=Wn(),n=null;function r(r){let i={"content-type":`application/json`},a=e();a&&(i.authorization=`Bearer ${a}`),fetch(`/page/presence`,{method:`POST`,keepalive:!0,headers:i,body:JSON.stringify({tabId:t,state:r})}).then(e=>{(e.status===404||e.status===204)&&n!==null&&(clearInterval(n),n=null)},()=>{})}r(`open`),n=setInterval(()=>r(`open`),2e4),window.addEventListener(`pagehide`,()=>r(`closed`)),window.addEventListener(`pageshow`,e=>{e.persisted&&r(`open`)})}function Kn(e,t,r,i=null){let a=n(`label`,`project-switcher select-wrap`);a.append(n(`span`,`visually-hidden`,`Project`));let o=n(`select`,`field project-select`);if(i){let e=n(`option`,void 0,`${i.name?`${i.name} · `:``}the board this server was started on`);e.value=``,e.selected=t===null,o.append(e)}for(let r of e){let e=n(`option`,void 0,`${r.name} · ${r.folder}`);e.value=r.id,e.selected=r.id===t,o.append(e)}return o.addEventListener(`change`,()=>r(o.value)),a.append(o),a}function qn(e,t){let r=n(`span`,`project-where`);if(r.append(n(`span`,`where-key`,t.identifier)),!e)return t.name&&r.append(` · ${t.name}`),r;let i=e.storage.kind===`file`?`board file ${e.storage.path}`:`Postgres at ${e.storage.where}`;return r.append(` · ${e.folder} · ${i}`),r}let Jn={urgent:`Urgent`,high:`High`,medium:`Medium`,low:`Low`,none:`None`};function Yn(e,t){return t?`${e.shown} of ${e.total}`:e.total===1?`1 card`:`${e.total} cards`}function Xn(e,t){return e.filter(e=>e!==t)}function Zn(e,t,r,i,...a){let o=n(`label`,`option`),s=n(`input`);return s.type=e,s.checked=r,s.dataset.key=t,s.addEventListener(`change`,i),o.append(s,...a),o}function Qn(e,...t){let r=n(`div`,`popover-section`);return r.setAttribute(`role`,`group`),r.setAttribute(`aria-label`,e),r.append(n(`p`,`popover-title`,e),...t),r}function $n(e){return+!!e.waiting+ +!!e.running+(e.worker===null?0:1)+e.priorities.length+e.labels.length}function er(e){let t={filters:Ye,display:xt,options:{workers:[],labels:[]},counts:{shown:0,total:0}},i=t=>e.onFilters(t),a=n(`div`,`toolbar-wrap`),o=n(`div`,`toolbar`);o.setAttribute(`role`,`search`);let s=n(`label`,`search-box`),c=n(`input`,`field filter-search`);c.type=`search`,c.placeholder=`Search cards`,c.setAttribute(`aria-label`,`Search cards`),c.addEventListener(`input`,()=>i({...t.filters,text:c.value})),c.addEventListener(`keydown`,e=>{e.key===`Escape`&&c.value!==``&&(e.stopPropagation(),c.value=``,i({...t.filters,text:``}))});let l=n(`button`,`icon-button search-clear`);l.type=`button`,l.setAttribute(`aria-label`,`Clear search`),l.append(He()),l.addEventListener(`click`,()=>{c.value=``,i({...t.filters,text:``}),c.focus()}),s.append(Ue(),c,l);let u=n(`span`,`toolbar-count`);u.setAttribute(`role`,`status`);let d=n(`span`,`anchor`),f=n(`button`,`tool-button filter-button`);f.type=`button`;let p=n(`span`,`badge`);f.append(We(),`Filter`,p),d.append(f);let m=n(`span`,`anchor`),h=n(`button`,`tool-button display-button`);h.type=`button`,h.append(Ge(),`Display`),m.append(h);let g=n(`div`,`view-switch`);g.setAttribute(`role`,`group`),g.setAttribute(`aria-label`,`View`);let ee=[`board`,`list`,`analytics`].map(r=>{let i=n(`button`);return i.type=`button`,i.dataset.view=r,i.title=r===`board`?`Board`:r===`list`?`List`:`Analytics`,i.setAttribute(`aria-label`,i.title),i.append(r===`board`?Ke():r===`list`?qe():Je()),i.addEventListener(`click`,()=>{t.display.view!==r&&e.onDisplay({...t.display,view:r})}),i});g.append(...ee);let _=n(`button`,`primary`);_.type=`button`,_.append(Ve(),`New`),_.addEventListener(`click`,e.onNew),o.append(s,u,n(`span`,`spacer`),d,m,g,_);let v=n(`div`,`filter-chips`);v.hidden=!0,a.append(o,v);let y=an(d,f,`Filter cards`,()=>{let{filters:e,options:r}=t,a=n(`div`);a.append(Qn(`Status`,Zn(`checkbox`,`waiting`,e.waiting,()=>i({...e,waiting:!e.waiting}),`Waiting for you`),Zn(`checkbox`,`running`,e.running,()=>i({...e,running:!e.running}),`Running now`)));let o=[{key:``,label:`Anyone`},{key:`nobody`,label:`Nobody`},...r.workers];e.worker!==null&&!o.some(t=>t.key===e.worker)&&o.push({key:e.worker,label:e.worker}),a.append(Qn(`Worked by`,...o.map(t=>Zn(`radio`,`who:${t.key}`,(e.worker??``)===t.key,()=>i({...e,worker:t.key===``?null:t.key}),t.label)))),a.append(Qn(`Priority`,...Xe.map(t=>{let n=e.priorities.includes(t);return Zn(`checkbox`,`priority:${t}`,n,()=>i({...e,priorities:n?Xn(e.priorities,t):[...e.priorities,t]}),Fe(t),Jn[t])})));let s=[.../* @__PURE__ */ new Set([...r.labels,...e.labels])];return s.length>0&&a.append(Qn(`Labels`,...s.map(t=>{let n=e.labels.includes(t);return Zn(`checkbox`,`label:${t}`,n,()=>i({...e,labels:n?Xn(e.labels,t):[...e.labels,t]}),t)}))),a},`start`),b=an(m,h,`Display options`,()=>{let r=n(`div`),i=t.display.subtasks===`cards`,a=n(`label`,`option`),o=n(`input`);return o.type=`checkbox`,o.setAttribute(`role`,`switch`),o.checked=i,o.dataset.key=`subtasks`,o.addEventListener(`change`,()=>e.onDisplay({...t.display,subtasks:i?`inside`:`cards`})),a.append(o,`Show sub-tasks as cards`),r.append(Qn(`Sub-tasks`,a,n(`p`,`option-hint`,`Off: a sub-task is a row inside its parent card. On: each is a card of its own, marked "Sub-task of".`))),r},`end`),x=(e,t)=>{let r=n(`button`,`filter-chip`);return r.type=`button`,r.title=`Remove: ${e}`,r.append(e,He()),r.addEventListener(`click`,t),r};function te(){let{filters:e}=t,n=e.worker===null?``:e.worker===`nobody`?`Nobody`:t.options.workers.find(t=>t.key===e.worker)?.label??e.worker,a=[...e.waiting?[x(`Waiting for you`,()=>i({...e,waiting:!1}))]:[],...e.running?[x(`Running now`,()=>i({...e,running:!1}))]:[],...e.worker===null?[]:[x(`Worked by: ${n}`,()=>i({...e,worker:null}))],...e.priorities.map(t=>x(`Priority: ${Jn[t]}`,()=>i({...e,priorities:Xn(e.priorities,t)}))),...e.labels.map(t=>x(`Label: ${t}`,()=>i({...e,labels:Xn(e.labels,t)})))];v.hidden=!et(e),v.replaceChildren(...a,...et(e)?[r(`Clear`,`ghost filter-clear`,()=>i(Ye))]:[])}return{element:a,update:e=>{t=e;let n=et(e.filters);c.value!==e.filters.text&&document.activeElement!==c&&(c.value=e.filters.text),l.hidden=c.value===``,u.textContent=Yn(e.counts,n);let r=$n(e.filters);p.textContent=String(r),p.hidden=r===0;for(let t of ee)t.setAttribute(`aria-pressed`,String(t.dataset.view===e.display.view));te();let i=e.display.view===`analytics`;for(let e of[s,u,d,m])e.hidden=i;v.hidden=i||!n,i&&(y.close(),b.close()),y.refresh(),b.refresh()}}}let tr=`kanbo-serve-token`;function nr(){try{return sessionStorage.getItem(tr)}catch{return null}}function rr(e){try{e?sessionStorage.setItem(tr,e):sessionStorage.removeItem(tr)}catch{}}function ir(){let e=new URLSearchParams(location.hash.slice(1)).get(`token`)?.trim();e&&(rr(e),history.replaceState(history.state,``,`${location.pathname}${location.search}`))}ir();let A=nr(),j=new URLSearchParams(location.search).get(`project`),M=[],N=null,ar=``,P=Oe(()=>A,()=>j===null?``:`/projects/${encodeURIComponent(j)}`),F=nt(location.search),I=sr(),L=St(location.search);function or(){try{return window.sessionStorage}catch{return null}}function sr(){let e=or();return e?qt(e,j??`default`):/* @__PURE__ */ new Set}function cr(e){I=new Set(I),I.delete(e)||I.add(e);let t=or();t&&Jt(t,j??`default`,I),Q()}let R=on,z=ue(P,()=>N?.id??null,()=>{ur=!0,L.view===`analytics`&&Q()}),lr=null,ur=!0,dr=!1,B=[],V=[],fr=null,pr=!1,mr=!1,hr=!1,H=null,U=null,W=null,G=null,gr=null,_r=null,vr=document.querySelector(`#app`)??document.body,yr=n(`header`,`topbar`),K=n(`input`,`field token-input`),br=r(`Token`,`ghost token-toggle`,()=>{Er=!Er,Dr(),Er&&K.focus()}),q=n(`p`,`notice`),J=n(`main`,`board`),Y=n(`div`,`panel-host`),xr=n(`span`,`project-slot`),Sr=n(`div`,`filter-slot`),Cr=pn({onMove:e=>{let t=B.find(t=>t.id===e);Wr({statusId:e},t?.name)},onPriority:e=>void Wr({priority:e}),onClear:()=>$(un())}),wr=er({onFilters:e=>zr(e),onDisplay:e=>Br(e),onNew:()=>{L.view===`analytics`&&Br({...L,view:`board`});let e=hn(B);e&&Xr(e)}}),Tr=!1,Er=!1;function Dr(){A===null||pr||!Tr?(Er=!1,delete yr.dataset.token):yr.dataset.token=Er?`unfolded`:`folded`,br.setAttribute(`aria-expanded`,String(yr.dataset.token!==`folded`))}function Or(){vr.classList.add(`app`);let e=n(`h1`,`topbar-title`,`Kanbo`),t=n(`span`,`workspace`);t.id=`workspace`,xr.id=`project-switcher`;let r=n(`form`,`token-form`);r.id=`token-form`,br.setAttribute(`aria-controls`,r.id),K.type=`password`,K.autocomplete=`off`,K.placeholder=`Server token`,K.value=A??``;let i=n(`label`,`token-label`,`Token`);i.append(K);let a=n(`button`,`secondary`,`Save`);a.type=`submit`,r.append(i,a),r.addEventListener(`submit`,e=>{e.preventDefault(),A=K.value.trim()||null,rr(A),pr=!1,Er=!1,X(null),Z()}),yr.append(e,xr,br,t,r),Dr(),q.setAttribute(`role`,`status`),q.hidden=!0,Sr.append(wr.element),vr.replaceChildren(yr,q,Sr,J,Cr.element,Y)}let kr=!1;function X(e,t=`info`){q.textContent=e??``,q.hidden=!e,q.dataset.kind=t,kr=!1}function Ar(e){return e instanceof De?e.code===`server_unreachable`?(mr=!0,e.message):e.status===401?(pr=!0,Dr(),K.focus(),`This server needs its token. Enter it in the Token field above.`):e.message:e instanceof Error?e.message:String(e)}function jr(e){X(Ar(e),`error`),kr=!0,Tr=!1,Dr()}function Mr(){Tr=!0,Dr(),kr&&(kr=!1,X(null))}async function Z(){if(!hr){hr=!0;try{let e=await P.version(),[t,n,r,i]=await Promise.all([P.statuses(),P.cards(),P.projects(),P.workspace()]);fr=e,B=t,V=n,R=dn(R,new Set(n.map(e=>e.id))),M=r,N=i,Vr(!0),Q(),Mr(),U&&await $r()}catch(e){Pr(e)||jr(e)}finally{hr=!1}Nr&&(Nr=!1,await Z())}}let Nr=!1;function Pr(e){if(!(e instanceof De)||e.code!==`project_not_found`||j===null)return!1;let t=M.find(e=>e.isDefault);return Fr(null),X(`That project is no longer on this computer's list; showing ${t?.name??`the board this server was started on`}.`),Nr=!0,!0}function Fr(e){j=e;let t=new URL(location.href);e===null?t.searchParams.delete(`project`):t.searchParams.set(`project`,e),F={...F,worker:null,labels:[]},I=sr(),R=on,z.reset(),dr=!1,ur=!0,Rr(t),fr=null,H=null,ii(),B=[],V=[],_r=null,N=null,ar=``,X(null)}async function Ir(){if(!(document.visibilityState!==`visible`||pr||mr||hr))try{await P.version()===fr?Mr():await Z()}catch(e){Pr(e)?await Z():jr(e)}}function Lr(){let e=j===null?M.find(e=>e.isDefault)??null:M.find(e=>e.id===j)??null,t=JSON.stringify([M,j,e?.id,N]);if(t===ar)return;ar=t;let n=M.some(e=>e.isDefault);xr.replaceChildren(...M.length>+!!n?[Kn(M,e?.id??null,e=>{Fr(e===``?null:e),Z()},n?null:{name:j===null?N?.name??null:null})]:[]);let r=document.querySelector(`#workspace`);r&&r.replaceChildren(...N?[qn(e,N)]:[])}function Rr(e=new URL(location.href)){history.replaceState(null,``,`${e.pathname}${Ct(L,rt(F,e.search))}${e.hash}`)}function zr(e){F=e,Rr(),Q()}function Br(e){let t=L;L=e,Rr(),e.view===`analytics`&&(R=on),e.view===`analytics`&&t.view===`analytics`&&(t.range!==e.range||t.sprint!==e.sprint)?z.show({weeks:e.range,sprint:e.sprint}):Vr(!1),Q()}function Vr(e){if(L.view!==`analytics`){z.hide(),dr=!1,lr?.dispose(),lr=null,ur=!0;return}let t={weeks:L.range,sprint:L.sprint};dr?e&&z.boardChanged():(dr=!0,z.show(t))}function Hr(){if(!ur&&J.querySelector(`.analytics`))return;let e=J.scrollTop;lr?.dispose(),lr=Ee(z.state(),{onQuery:e=>Br({...L,range:e.weeks,sprint:e.sprint}),onRetry:()=>z.retry(),onOpenCard:e=>void Qr(e)}),J.replaceChildren(lr.element),J.scrollTop=e,ur=!1}function Q(){Lr();let e=H!==null&&document.activeElement===H.input,t=document.activeElement?.closest(`.card, .list-row`)?.dataset.cardId??null,n=Bt(V,L.subtasks,e=>Qe(e,F)),r=Ft(V,L.subtasks).filter(e=>n.drawn.has(e.id));wr.update({filters:F,display:L,options:$e(V),counts:{shown:n.count,total:V.length}});let i={shown:At(V,e=>Qe(e,F)),total:At(V)},a=mn(B,r);if(J.dataset.view=L.view,L.view===`analytics`)Hr();else if(L.view===`list`){let e=Xt({statuses:B,cards:V,groups:a,mode:L.subtasks,faded:n.faded,collapsed:I,tally:i,now:Math.floor(Date.now()/1e3),onToggleGroup:cr,onOpen:e=>void Qr(e)});H&&(H.form.classList.add(`list-draft`),e.prepend(H.form)),J.replaceChildren(e)}else J.replaceChildren(...a.map(e=>Jr(e,n.faded,i)));_r=wt(V),Kr(),Ur(),e?H?.input.focus():t&&qr(t)}function Ur(){for(let e of J.querySelectorAll(`.card, .list-row`)){let t=e.dataset.cardId!==void 0&&R.ids.has(e.dataset.cardId);e.toggleAttribute(`data-selected`,t);let n=e.querySelector(`input.select-box`);n&&(n.checked=t)}Cr.update({count:R.ids.size,statuses:B})}function $(e){R=e,Ur()}async function Wr(e,t){try{X(await Ae(P,[...R.ids],e,{column:t}))}catch(e){X(Ar(e),`error`)}await Z()}function Gr(e,t){let n=[...(e.closest(`.column-cards, .list-group`)??J).querySelectorAll(`[data-card-id]`)].map(e=>e.dataset.cardId);$(cn(R,n,t))}J.addEventListener(`click`,e=>{let t=e.target,n=t.closest(`.card, .list-row`),r=n?.dataset.cardId;if(n&&r){if(e.shiftKey||e.metaKey||e.ctrlKey){if(t.closest(`.subtask-row, .subtask-more, .subtask-strip`))return;e.preventDefault(),e.stopPropagation(),e.shiftKey?Gr(n,r):$(sn(R,r))}else t.classList.contains(`select-box`)&&$(sn(R,r))}},!0);function Kr(){for(let e of J.querySelectorAll(`.card, .list-row`))e.toggleAttribute(`data-open`,e.dataset.cardId===U)}function qr(e){for(let t of J.querySelectorAll(`.card, .list-row`))t.dataset.cardId===e&&t.querySelector(`.card-title, .list-title`)?.focus()}function Jr(e,t,r){let i=n(`section`,`column`);i.setAttribute(`aria-label`,e.name);let a=n(`header`,`column-head`),o=e.status,s=Dt(o,o?r.shown.get(o.id)??0:e.cards.length,o?r.total.get(o.id)??0:e.cards.length),c=n(`span`,`column-count`,s.text);c.toggleAttribute(`data-full`,s.full),o?.wipLimit!=null&&(c.title=`${r.total.get(o.id)??0} of ${o.wipLimit} cards`),a.append(E(o?.category??null),n(`span`,`column-name`,e.name),c);let l=o?kt(o,B):null;if(l){let e=n(`span`,`column-lock`);e.append(Re()),e.title=l,e.setAttribute(`role`,`img`),e.setAttribute(`aria-label`,l.replaceAll(`
|
|
5
|
+
`,`. `)),a.append(e)}if(a.append(n(`span`,`spacer`)),o){let t=n(`button`,`ghost column-add`);t.type=`button`,t.append(Ve()),t.setAttribute(`aria-label`,`New card in ${e.name}`),t.title=`New card in ${e.name}`,t.addEventListener(`click`,()=>Xr(o)),a.append(t)}let u=n(`div`,`column-cards`);H&&H.statusId===e.id&&u.append(H.form);for(let n of e.cards){let e=L.subtasks===`inside`,r=bt(n,o?.category??null,e=>void Qr(e.id),{parent:Nt(V,n),summary:Mt(V,B,n.id),onOpenCard:e=>void Qr(e),block:e?Ut(V,B,n.id,t)??void 0:void 0,waitsBelow:e&&Rt(V,n.id),runsBelow:e&&zt(V,n.id)}),i=Tt(_r,n);i&&(r.dataset.enter=i),Et(_r,n)&&r.querySelector(`.waiting-pill`)?.setAttribute(`data-enter`,`waiting`),r.addEventListener(`dragstart`,e=>{gr=n.id,e.dataTransfer?.setData(`text/plain`,n.id),r.classList.add(`dragging`)}),r.addEventListener(`dragend`,()=>{gr=null,r.classList.remove(`dragging`)}),u.append(r)}return i.append(a,u),o&&(i.addEventListener(`dragover`,e=>{gr&&(e.preventDefault(),i.classList.add(`drop-target`))}),i.addEventListener(`dragleave`,e=>{i.contains(e.relatedTarget)||i.classList.remove(`drop-target`)}),i.addEventListener(`drop`,e=>{e.preventDefault(),i.classList.remove(`drop-target`);let t=gr;gr=null,t&&Yr(t,o)})),i}async function Yr(e,t){if(V.find(t=>t.id===e)?.statusId!==t.id){try{let n=await P.moveCard(e,t.id),r=n.unmetRules??[];X(r.length>0?`${n.id} is in ${t.name}, but still misses: ${r.map(e=>e.detail).join(`; `)}`:null)}catch(e){X(Ar(e),`error`)}await Z()}}function Xr(e){let t=n(`div`,`draft`),i=n(`textarea`,`field`);i.rows=3,i.placeholder=`Describe the card`,i.setAttribute(`aria-label`,`New card in ${e.name}`);let a=async()=>{let t=i.value.trim();if(!t){i.focus();return}try{let n=await P.createCard({workspaceId:e.workspaceId,statusId:e.id,description:t});H=null,X(n.unmetRules?.length?`${n.id} is in ${e.name}, but still misses: ${n.unmetRules.map(e=>e.detail).join(`; `)}`:null)}catch(e){X(Ar(e),`error`)}await Z()},o=()=>{H=null,Q()};i.addEventListener(`keydown`,e=>{e.key===`Enter`&&(e.metaKey||e.ctrlKey)?(e.preventDefault(),a()):e.key===`Escape`&&(e.stopPropagation(),o())});let s=n(`div`,`row`);s.append(r(`Create`,`primary`,()=>void a()),r(`Cancel`,`ghost`,o)),t.append(i,s),H={statusId:e.id,form:t,input:i},Q(),i.focus()}let Zr=`comments`;async function Qr(e){U=e,G=null,Kr(),await $r()}async function $r(){let e=U,t=V.find(t=>t.id===e);if(!e||!t){ii();return}if(!(W?.card.id===e&&ei(Y))){try{let[n,r,i,a]=await Promise.all([P.comments(e),P.activity(e),P.runs(e),P.fieldChanges(e)]);W={card:t,status:B.find(e=>e.id===t.statusId)??null,comments:n,activity:r,runs:i,fieldChanges:a,parent:Nt(V,t),subtasks:Ht(V,B,e),summary:Mt(V,B,e),siblings:t.parentIssueId&&t.parentIssueId!==e?jt(V,B,t.parentIssueId):[],statuses:B,tab:Zr}}catch(e){G=Ar(e)}ti()}}function ei(e){return[...e.querySelectorAll(`textarea`)].some(e=>e.value.trim()!==``||document.activeElement===e)}function ti(){if(!W||W.card.id!==U){Y.replaceChildren(),ri(!1);return}let e=W.card.id,t=On(W,{close:ii,addComment:t=>void ni(async()=>{await P.addComment(e,t)}),approve:t=>void ni(async()=>{await P.approve(e,t)}),returnCard:t=>void ni(async()=>{await P.returnCard(e,t)}),openCard:e=>void Qr(e),selectTab:e=>{Zr=e,W&&={...W,tab:e}}},G),n=!Y.firstChild,r=Dn(Y,e);Y.replaceChildren(t);let i=t.querySelector(`.panel-scroll`);i&&(i.scrollTop=r),n&&(ri(!0),t.classList.add(`panel--opening`),t.tabIndex=-1,t.focus())}async function ni(e){try{await e(),G=null;for(let e of Y.querySelectorAll(`textarea`))e.value=``}catch(e){let t=Ar(e);G=e instanceof De&&e.status===403?`${t} Needs the server token: only a request holding the token this server was started with acts for a person.`:t;let n=Y.querySelector(`.panel-notice`);n&&(n.textContent=G,n.hidden=!1);return}await Z()}function ri(e){for(let t of[yr,q,Sr,J,Cr.element])t.inert=e}Y.addEventListener(`click`,e=>{e.target===Y&&ii()});function ii(){let e=U;U=null,W=null,G=null,Y.replaceChildren(),ri(!1),Kr(),e&&qr(e)}let ai={layout:()=>en(J),focusedId:()=>document.activeElement?.closest(`.card, .list-row`)?.dataset.cardId??null,focus:qr,state:()=>({typing:$t(document.activeElement),popoverOpen:nn(),dialogOpen:U!==null,hasSelection:R.ids.size>0}),open:e=>void Qr(e),toggle:e=>$(sn(R,e)),extend:(e,t)=>$(ln(R,e,t)),search:()=>Sr.querySelector(`.filter-search`)?.focus(),closeDialog:ii,closePopover:()=>void rn(),clearSelection:()=>$(un())};document.addEventListener(`keydown`,e=>void tn(e,ai)),document.addEventListener(`keyup`,e=>{e.key===` `&&e.target instanceof HTMLElement&&e.target.closest(`.card-title, .list-title`)&&e.preventDefault()}),document.addEventListener(`visibilitychange`,()=>void Ir()),Or(),Z(),setInterval(()=>void Ir(),2e3),Gn(()=>A)})();
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
Copyright 2024 The Geist Project Authors (https://github.com/vercel/geist-font) Geist-Italic[wght].ttf: Copyright 2024 The Geist Project Authors (https://github.com/vercel/geist-font)
|
|
2
|
+
|
|
3
|
+
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
|
4
|
+
This license is copied below, and is also available with a FAQ at:
|
|
5
|
+
http://scripts.sil.org/OFL
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
-----------------------------------------------------------
|
|
9
|
+
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
|
10
|
+
-----------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
PREAMBLE
|
|
13
|
+
The goals of the Open Font License (OFL) are to stimulate worldwide
|
|
14
|
+
development of collaborative font projects, to support the font creation
|
|
15
|
+
efforts of academic and linguistic communities, and to provide a free and
|
|
16
|
+
open framework in which fonts may be shared and improved in partnership
|
|
17
|
+
with others.
|
|
18
|
+
|
|
19
|
+
The OFL allows the licensed fonts to be used, studied, modified and
|
|
20
|
+
redistributed freely as long as they are not sold by themselves. The
|
|
21
|
+
fonts, including any derivative works, can be bundled, embedded,
|
|
22
|
+
redistributed and/or sold with any software provided that any reserved
|
|
23
|
+
names are not used by derivative works. The fonts and derivatives,
|
|
24
|
+
however, cannot be released under any other type of license. The
|
|
25
|
+
requirement for fonts to remain under this license does not apply
|
|
26
|
+
to any document created using the fonts or their derivatives.
|
|
27
|
+
|
|
28
|
+
DEFINITIONS
|
|
29
|
+
"Font Software" refers to the set of files released by the Copyright
|
|
30
|
+
Holder(s) under this license and clearly marked as such. This may
|
|
31
|
+
include source files, build scripts and documentation.
|
|
32
|
+
|
|
33
|
+
"Reserved Font Name" refers to any names specified as such after the
|
|
34
|
+
copyright statement(s).
|
|
35
|
+
|
|
36
|
+
"Original Version" refers to the collection of Font Software components as
|
|
37
|
+
distributed by the Copyright Holder(s).
|
|
38
|
+
|
|
39
|
+
"Modified Version" refers to any derivative made by adding to, deleting,
|
|
40
|
+
or substituting -- in part or in whole -- any of the components of the
|
|
41
|
+
Original Version, by changing formats or by porting the Font Software to a
|
|
42
|
+
new environment.
|
|
43
|
+
|
|
44
|
+
"Author" refers to any designer, engineer, programmer, technical
|
|
45
|
+
writer or other person who contributed to the Font Software.
|
|
46
|
+
|
|
47
|
+
PERMISSION & CONDITIONS
|
|
48
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
49
|
+
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
|
50
|
+
redistribute, and sell modified and unmodified copies of the Font
|
|
51
|
+
Software, subject to the following conditions:
|
|
52
|
+
|
|
53
|
+
1) Neither the Font Software nor any of its individual components,
|
|
54
|
+
in Original or Modified Versions, may be sold by itself.
|
|
55
|
+
|
|
56
|
+
2) Original or Modified Versions of the Font Software may be bundled,
|
|
57
|
+
redistributed and/or sold with any software, provided that each copy
|
|
58
|
+
contains the above copyright notice and this license. These can be
|
|
59
|
+
included either as stand-alone text files, human-readable headers or
|
|
60
|
+
in the appropriate machine-readable metadata fields within text or
|
|
61
|
+
binary files as long as those fields can be easily viewed by the user.
|
|
62
|
+
|
|
63
|
+
3) No Modified Version of the Font Software may use the Reserved Font
|
|
64
|
+
Name(s) unless explicit written permission is granted by the corresponding
|
|
65
|
+
Copyright Holder. This restriction only applies to the primary font name as
|
|
66
|
+
presented to the users.
|
|
67
|
+
|
|
68
|
+
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
|
69
|
+
Software shall not be used to promote, endorse or advertise any
|
|
70
|
+
Modified Version, except to acknowledge the contribution(s) of the
|
|
71
|
+
Copyright Holder(s) and the Author(s) or with their explicit written
|
|
72
|
+
permission.
|
|
73
|
+
|
|
74
|
+
5) The Font Software, modified or unmodified, in part or in whole,
|
|
75
|
+
must be distributed entirely under this license, and must not be
|
|
76
|
+
distributed under any other license. The requirement for fonts to
|
|
77
|
+
remain under this license does not apply to any document created
|
|
78
|
+
using the Font Software.
|
|
79
|
+
|
|
80
|
+
TERMINATION
|
|
81
|
+
This license becomes null and void if any of the above conditions are
|
|
82
|
+
not met.
|
|
83
|
+
|
|
84
|
+
DISCLAIMER
|
|
85
|
+
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
86
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
|
87
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
|
88
|
+
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
|
89
|
+
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
90
|
+
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
|
91
|
+
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
92
|
+
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
|
93
|
+
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|