@xauyxau/hnch 1.13.0 → 1.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +10 -10
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import ea from'yargs';import {hideBin}from'yargs/helpers';import Qt,{useState,useEffect,useCallback,useMemo,useRef}from'react';import {render,useApp,useInput,Box,Text}from'ink';import*as $e from'yjs';import {Awareness}from'y-protocols/awareness';import {existsSync,readFileSync,writeFileSync,unlinkSync,mkdirSync,chmodSync}from'fs';import {homedir}from'os';import {join}from'path';import {randomUUID}from'crypto';import {createInterface}from'readline';import {WebsocketProvider}from'y-websocket';import es from'ws';import Cr from'clipboardy';import {jsxs,jsx,Fragment}from'react/jsx-runtime';var It="hnch_abstain";function W(e){return e===It}var pi={"unknown-room":4001,"wrong-password":4002,"invalid-invite":4003,"expired-invite":4004,"invite-already-redeemed":4005,"room-full":4006,"malformed-credentials":4010},Qn=new Map(Object.entries(pi).map(([e,t])=>[t,e]));function Ie(e){return e.role??"voter"}function Tt(e){return e.leftAt===void 0}function _(e){let{revealedAt:t,skippedAt:n,discardedAt:o}=e;if(t===void 0&&n===void 0&&o===void 0)return null;let r=[];t!==void 0&&r.push({kind:"revealed",at:t}),n!==void 0&&r.push({kind:"skipped",at:n}),o!==void 0&&r.push({kind:"discarded",at:o});let i={revealed:0,skipped:1,discarded:2};return r.sort((s,a)=>s.at-a.at||i[s.kind]-i[a.kind]),r[0].kind}var Rt={id:"fibonacci",cards:["0","1","2","3","5","8","13","21"]},Zn={id:"t-shirt",cards:["XS","S","M","L","XL"]},eo={id:"powers-of-2",cards:["1","2","4","8","16","32","64"]},to={id:"linear",cards:["1","2","3","4","5","6","7","8","9","10"]},no={id:"risk",cards:["Low","Medium","High","Critical"]},de={[Rt.id]:Rt,[Zn.id]:Zn,[eo.id]:eo,[to.id]:to,[no.id]:no},oo={fibonacci:"Fibonacci","t-shirt":"T-shirt","powers-of-2":"Powers of 2",linear:"Linear (1\u201310)",risk:"Risk"};function ro(e){return e in oo?oo[e]:e.length===0?e:(e.startsWith("custom-")?e.slice(7):e).split("-").map(n=>n.length===0?n:n.charAt(0).toUpperCase()+n.slice(1)).join(" ")}function io(e,t,n){if(!e||_(e)!==null)return false;let o=new Set(t.filter(d=>Tt(d)&&n.has(d.id)&&Ie(d)!=="viewer").map(d=>d.id));if(o.size===0)return false;let r=Object.entries(e.votes).filter(([d])=>o.has(d)),i=r.filter(([,d])=>W(d)).length,s=r.length-i,a=o.size-i;return a<=0?false:s>=a}var ze={"racing-green":{base:"#0B3D2E",soft:"rgba(11,61,46,0.14)",ink:"#fff",label:"Racing Green"},dijon:{base:"#C9A227",soft:"rgba(201,162,39,0.18)",ink:"#000",label:"Dijon"},blue:{base:"#0A84FF",soft:"rgba(10,132,255,0.14)",ink:"#fff",label:"Blue"},indigo:{base:"#5E5CE6",soft:"rgba(94,92,230,0.14)",ink:"#fff",label:"Indigo"},violet:{base:"#BF5AF2",soft:"rgba(191,90,242,0.14)",ink:"#fff",label:"Violet"},pink:{base:"#FF375F",soft:"rgba(255,55,95,0.14)",ink:"#fff",label:"Pink"},red:{base:"#FF453A",soft:"rgba(255,69,58,0.14)",ink:"#fff",label:"Red"},orange:{base:"#FF9F0A",soft:"rgba(255,159,10,0.16)",ink:"#000",label:"Orange"},amber:{base:"#FFD60A",soft:"rgba(255,214,10,0.18)",ink:"#000",label:"Amber"},green:{base:"#30D158",soft:"rgba(48,209,88,0.14)",ink:"#000",label:"Green"},teal:{base:"#40C8E0",soft:"rgba(64,200,224,0.14)",ink:"#000",label:"Teal"},graphite:{base:"#1C1C1E",soft:"rgba(28,28,30,0.10)",ink:"#fff",label:"Graphite"}};var at=["racing-green","dijon","blue","indigo","violet","pink","red","orange","amber","green","teal","graphite"],fi=/^#[0-9a-fA-F]{6}$/;function mi(e){return Object.hasOwn(ze,e)}function Me(e){return e?mi(e)?ze[e].base:fi.test(e)?e.toLowerCase():null:null}function so(e){let t=5381;for(let o=0;o<e.length;o++)t=(t<<5)+t+e.charCodeAt(o)|0;let n=Math.abs(t)%at.length;return at[n]}var Re="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",Et=Re.length,un=Math.floor(Et/2);function dt(e){let t=Re.indexOf(e);if(t===-1)throw new Error(`fractional-index: invalid character '${e}'`);return t}function ao(e,t){return e.length>=t?e:e+"0".repeat(t-e.length)}function gi(e){let t=e.length-1;for(;t>0&&e[t]==="0";)t--;return e.slice(0,t+1)}function hi(e,t){let n=e.length,o=Array.from({length:n+1}).fill(0),r=0;for(let a=n-1;a>=0;a--){let d=e[a]+t[a]+r;o[a+1]=d%Et,r=Math.floor(d/Et);}o[0]=r;let i=Array.from({length:n+1}).fill(0),s=0;for(let a=0;a<=n;a++){let d=o[a]+s*Et;i[a]=Math.floor(d/2),s=d%2;}return i.slice(1)}function pn(e,t){let n=Re[un];if(e===null&&t===null)return n+n;if(t===null)return e+n+n+n+n;if(e===null)return Si(t);if(e>=t)throw new Error(`keyBetween: a must be < b (a='${e}', b='${t}')`);return wi(e,t)}function Si(e){for(let t=e.length-1;t>=0;t--){let n=dt(e[t]);if(n>0)return e.slice(0,t)+Re[n-1]+Re[un]}if(e.length>1)return e.slice(0,-1);throw new Error(`keyBetween: cannot generate key before '${e}' \u2014 use keyBetween(null, null) for the initial key`)}function wi(e,t){let n=Math.max(e.length,t.length),o=ao(e,n).split("").map(d=>dt(d)),r=ao(t,n).split("").map(d=>dt(d)),s=hi(o,r).map(d=>Re[d]).join(""),a=gi(s);return a>e&&a<t?a:s>e&&s<t?s:xi(e,t)}function xi(e,t){for(let n=0;n<t.length;n++){let o=n<e.length?dt(e[n]):0;if(dt(t[n])===o+1)return (n<e.length?e.slice(0,n+1):e+Re[0])+Re[un]}throw new Error(`keyBetween: space exhausted between '${e}' and '${t}'`)}var yi="meta",Pt="settings",vi="participants",Ci="rounds",bi="agenda",Ai=["roomUuid","createdAt","createdBy","sessionEndedAt"],Ii=["name","defaultScale","hostParticipantId"],Ri=["displayName","joinedAt","role","leftAt","removedBy","avatarColor"],Ti=["id","title","description","ticketId","state","source","externalId","sortKey","createdAt","consumedAt","consumedByRoundId"],Ei=["id","title","description","ticketId","parentRoundId","scale","timerStartedAt","revealedAt","skippedAt","discardedAt","discardedBy","createdBy","createdAt","agendaItemId"];function kt(e){return e.getMap(yi)}function Dt(e){return e.getMap(Pt)}function Ot(e){return e.getMap(vi)}function fn(e){return e.getArray(Ci)}function Nt(e){return e.getArray(bi)}function ct(e,t){let n={};for(let o of t){let r=e.get(o);r!==void 0&&(n[o]=r);}return n}function ki(e){return ct(kt(e),Ai)}function Ni(e){return ct(Dt(e),Ii)}function Pi(e){let t=Ot(e),n=[];return t.forEach((o,r)=>{let i=ct(o,Ri);n.push({id:r,...i});}),n.sort((o,r)=>o.joinedAt-r.joinedAt||o.id.localeCompare(r.id)),n}function Di(e){let t={};return e.forEach((n,o)=>{t[o]=n;}),t}function Oi(e){let t=ct(e,Ei),n=e.get("votes"),o=n?Di(n):{};return {...t,votes:o}}function Mi(e){let t=fn(e),n=[];return t.forEach(o=>{n.push(Oi(o));}),n}function $i(e){return ct(e,Ti)}function Ui(e){let t=Nt(e),n=[];return t.forEach(o=>{n.push($i(o));}),n.sort((o,r)=>o.sortKey.localeCompare(r.sortKey)),n}function j(e){return {meta:ki(e),settings:Ni(e),participants:Pi(e),rounds:Mi(e),agenda:Ui(e)}}function co(e,t){if(kt(e).has("roomUuid"))throw new Error("initDoc: doc already seeded");e.transact(()=>{let n=kt(e);n.set("roomUuid",t.roomUuid),n.set("createdAt",t.createdAt),n.set("createdBy",t.participantId);let o=Dt(e);t.sessionName!==void 0&&o.set("name",t.sessionName),o.set("defaultScale",t.defaultScale),o.set("hostParticipantId",t.participantId);let r=new $e.Map;r.set("displayName",t.displayName),r.set("joinedAt",t.createdAt),t.avatarColor!==void 0&&r.set("avatarColor",t.avatarColor),Ot(e).set(t.participantId,r);});}function Xe(e,t){e.transact(()=>{let n=Ot(e),o=n.get(t.participantId),r=o??new $e.Map;r.set("displayName",t.displayName),o===void 0&&r.set("joinedAt",Date.now()),t.avatarColor!==void 0&&r.set("avatarColor",t.avatarColor),r.delete("leftAt"),r.delete("removedBy"),o===void 0&&n.set(t.participantId,r);});}function Qe(e,t){e.transact(()=>{let n=Dt(e);for(let[o,r]of Object.entries(t))r===void 0?n.delete(o):n.set(o,r);});}function mn(e,t,n){e.transact(()=>{let o=Ot(e),r=o.get(t),i=r??new $e.Map;i.set("displayName",n.displayName),i.set("joinedAt",n.joinedAt),n.role!==void 0&&i.set("role",n.role),n.avatarColor!==void 0&&i.set("avatarColor",n.avatarColor),r===void 0&&o.set(t,i);});}function gn(e,t){let n=t.scale??Dt(e).get("defaultScale");if(!n)throw new Error("appendRound: no scale (settings.defaultScale missing)");if(t.parentRoundId!==void 0){let o=Ue(e,t.parentRoundId);if(o!==void 0&&o.get("discardedAt")!==void 0)throw new Error(`appendRound: parentRoundId ${t.parentRoundId} points at a discarded round`)}return e.transact(()=>{let o=new $e.Map;o.set("id",t.id),o.set("createdAt",t.createdAt),o.set("createdBy",t.createdBy),o.set("scale",n),t.title!==void 0&&o.set("title",t.title),t.description!==void 0&&o.set("description",t.description),t.ticketId!==void 0&&o.set("ticketId",t.ticketId),t.parentRoundId!==void 0&&o.set("parentRoundId",t.parentRoundId),t.agendaItemId!==void 0&&o.set("agendaItemId",t.agendaItemId),o.set("timerStartedAt",t.createdAt),o.set("votes",new $e.Map),fn(e).push([o]);}),t.id}function lo(e,t,n){let o=Ue(e,t);if(!o)throw new Error(`patchRoundDescriptor: round ${t} not found`);e.transact(()=>{n.title!==void 0&&o.set("title",n.title),n.description!==void 0&&o.set("description",n.description);});}function Ue(e,t){let n=fn(e);for(let o=0;o<n.length;o+=1){let r=n.get(o);if(r.get("id")===t)return r}}function uo(e,t,n,o){let r=Ue(e,t);if(!r)throw new Error(`castVote: round ${t} not found`);r.get("revealedAt")===void 0&&e.transact(()=>{r.get("votes").set(n,o);});}function po(e,t,n){let o=Ue(e,t);if(!o)throw new Error(`clearVote: round ${t} not found`);o.get("revealedAt")===void 0&&e.transact(()=>{o.get("votes").delete(n);});}function fo(e,t,n,o){let r=t.get("agendaItemId");if(r===void 0)return;let i=Sn(e,r);i!==void 0&&i.get("state")==="pending"&&(i.set("state","consumed"),i.set("consumedAt",o),i.set("consumedByRoundId",n));}function hn(e,t,n){let o=Ue(e,t);if(!o)throw new Error(`revealRound: round ${t} not found`);if(o.get("skippedAt")!==void 0)throw new Error(`revealRound: round ${t} already skipped`);if(o.get("discardedAt")!==void 0)throw new Error(`revealRound: round ${t} already discarded`);e.transact(()=>{o.set("revealedAt",n),fo(e,o,t,n);});}function mo(e,t,n){let o=Ue(e,t);if(!o)throw new Error(`skipRound: round ${t} not found`);if(o.get("revealedAt")!==void 0)throw new Error(`skipRound: round ${t} already revealed`);if(o.get("skippedAt")!==void 0)throw new Error(`skipRound: round ${t} already skipped`);if(o.get("discardedAt")!==void 0)throw new Error(`skipRound: round ${t} already discarded`);e.transact(()=>{o.set("skippedAt",n),fo(e,o,t,n);});}function go(e,t,n,o){let r=Ue(e,t);if(!r)throw new Error(`discardRound: round ${t} not found`);if(r.get("revealedAt")!==void 0)throw new Error(`discardRound: round ${t} already revealed`);if(r.get("skippedAt")!==void 0)throw new Error(`discardRound: round ${t} already skipped`);if(r.get("discardedAt")!==void 0)throw new Error(`discardRound: round ${t} already discarded`);e.transact(()=>{r.set("discardedAt",n),r.set("discardedBy",o);});}function ho(e){e.transact(()=>{kt(e).set("sessionEndedAt",Date.now());});}function q(e){let{rounds:t}=e;if(t.length===0)return null;for(let n=t.length-1;n>=0;n-=1){let o=t[n];if(o.revealedAt===void 0&&o.skippedAt===void 0&&o.discardedAt===void 0)return o}for(let n=t.length-1;n>=0;n-=1){let o=t[n];if(o.discardedAt===void 0)return o}return null}function So(e){let t=Object.values(e.votes);return t.length<2?false:t.every(n=>n===t[0])}function Sn(e,t){let n=Nt(e);for(let o=0;o<n.length;o++){let r=n.get(o);if(r.get("id")===t)return r}}function Mt(e,t){if(!t.title?.trim()&&!t.ticketId?.trim())throw new Error("appendAgendaItem: at least one of {title, ticketId} is required");let n=crypto.randomUUID(),o=Nt(e),r=null;o.forEach(s=>{if(s.get("state")==="pending"){let a=s.get("sortKey");a!==void 0&&(r===null||a>r)&&(r=a);}});let i=pn(r,null);return e.transact(()=>{let s=new $e.Map;s.set("id",n),s.set("state","pending"),s.set("source",t.source??"manual"),s.set("sortKey",i),s.set("createdAt",t.createdAt),t.title!==void 0&&s.set("title",t.title),t.description!==void 0&&s.set("description",t.description),t.ticketId!==void 0&&s.set("ticketId",t.ticketId),t.externalId!==void 0&&s.set("externalId",t.externalId),Nt(e).push([s]);}),n}function wn(e,t,n,o={}){let r=Sn(e,t);if(!r)throw new Error(`setAgendaItemState: item ${t} not found`);let i=r.get("state");if(!(i===n&&n==="consumed")){if(i!=="pending")throw new Error(`setAgendaItemState: invalid transition '${i}' \u2192 '${n}' for item ${t}`);e.transact(()=>{r.set("state",n),n==="consumed"&&(r.set("consumedAt",o.timestamp??Date.now()),o.consumedByRoundId!==void 0&&r.set("consumedByRoundId",o.consumedByRoundId));});}}function wo(e,t,n,o){let r=Sn(e,t);if(!r)throw new Error(`reorderAgendaItem: item ${t} not found`);let i=r.get("state");if(i!=="pending")throw new Error(`reorderAgendaItem: item ${t} is ${i}; only pending items may be reordered`);let s=pn(n??null,o??null);e.transact(()=>{r.set("sortKey",s);});}function Ze(e){for(let t of e.agenda)if(t.state==="pending")return t;return null}var xo=5e3;function yo(e,t){let n=new Set;for(let o of e.participants)t.has(o.id)&&Tt(o)&&n.add(o.id);return n}function vo(e,t,n){let o=e.settings.hostParticipantId;return o?yo(e,t).has(o)?{kind:"cancel"}:n.missingHostId!==o?{kind:"start-debounce",hostId:o}:{kind:"none"}:{kind:"none"}}function Co(e,t,n,o){let r=e.settings.hostParticipantId;if(!o||r!==o)return {promote:false};let i=yo(e,t);if(i.has(r))return {promote:false};let s=[...i].toSorted();if(s.length===0)return {promote:false};let a=s[0];return a!==n?{promote:false}:{promote:true,winner:a}}function bo(e){let t=Math.max(0,Math.floor(e/1e3)),n=Math.floor(t/60),o=t%60;return `${n}:${o.toString().padStart(2,"0")}`}function Ao(e){try{let t=new URL(e);return t.protocol==="http:"||t.protocol==="https:"}catch{return false}}function xn(e){if(e===null||typeof e!="object"||Array.isArray(e))return {version:2,entries:{}};let t=e;if(t.version===2&&Ro(t.entries)){let n=t.entries,o={};for(let[r,i]of Object.entries(n)){let s=Bi(i);s!==null&&(o[r]=s);}return {version:2,entries:o}}if(typeof t.roomCode=="string"&&typeof t.roomUuid=="string"&&typeof t.lastSeenAt=="number"){let n={roomCode:t.roomCode,roomUuid:t.roomUuid,lastSeenAt:t.lastSeenAt,...typeof t.passwordHash=="string"?{passwordHash:t.passwordHash}:{}};return {version:2,entries:{[n.roomUuid]:n}}}return {version:2,entries:{}}}function Io(e,t,n=864e5){let o={};for(let[r,i]of Object.entries(e.entries))t-i.lastSeenAt>n||(i.lastSeenAt>t?o[r]={...i,lastSeenAt:t}:o[r]=i);return {version:2,entries:o}}function Ro(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function Bi(e){if(!Ro(e))return null;let t=e;return typeof t.roomCode!="string"||typeof t.roomUuid!="string"||typeof t.lastSeenAt!="number"?null:{roomCode:t.roomCode,roomUuid:t.roomUuid,lastSeenAt:t.lastSeenAt,...typeof t.passwordHash=="string"?{passwordHash:t.passwordHash}:{}}}function To(e,t){let n=t.filter(p=>p.discardedAt===void 0),o=new Map;for(let p of n)o.set(p.id,p);let r=o.get(e);if(r===void 0||r.parentRoundId===void 0)return null;let i=new Set([r.id]),s=r,a=1;for(;s.parentRoundId!==void 0;){let p=o.get(s.parentRoundId);if(p===void 0||i.has(p.id))return null;i.add(p.id),s=p,a+=1;}let d=s,u=new Map;for(let p of n){if(p.parentRoundId===void 0)continue;let I=u.get(p.parentRoundId);I===void 0?u.set(p.parentRoundId,[p]):I.push(p);}let c=0,l=[d];for(;l.length>0;){let p=l.shift();c+=1;let I=u.get(p.id);I!==void 0&&l.push(...I);}return {chainRoot:d,depth:a,total:c}}var Eo="PBKDF2",Hi="SHA-256",ko=new TextEncoder;function Li(e){return Array.from(new Uint8Array(e)).map(t=>t.toString(16).padStart(2,"0")).join("")}async function Be(e,t){let n=await crypto.subtle.importKey("raw",ko.encode(e),Eo,false,["deriveBits"]),o=await crypto.subtle.deriveBits({name:Eo,salt:ko.encode(t),iterations:1e5,hash:Hi},n,256);return Li(o)}var No="ABCDEFGHJKMNPQRSTUVWXYZ23456789";if(No.length!==31)throw new Error(`Room code alphabet must be 31 characters, got ${No.length}`);function yn(e){return e.trim().replaceAll(/-/g,"").toUpperCase()}function Po(e,t=true){let n=yn(e);return !t||n.length!==6?n:`${n.slice(0,3)}-${n.slice(3)}`}function Do(e){let t=new Set(e).size;return t===1?"unanimous":t===2?"close":"spread"}function ji(e,t){let n=new Map;t.forEach((i,s)=>n.set(i,s));let o=[...new Set(e.filter(i=>!n.has(i)))].toSorted(),r=new Map;return o.forEach((i,s)=>r.set(i,t.length+s)),i=>n.get(i)??r.get(i)??Number.MAX_SAFE_INTEGER}function vn(e,t){let n=new Map;for(let s of e)n.set(s,(n.get(s)??0)+1);let o=null,r=0,i=[...n.keys()].toSorted((s,a)=>t(s)-t(a));for(let s of i){let a=n.get(s);a>r&&(r=a,o=s);}return o}function Oo(e,t){let n=Object.values(e);if(n.length===0)return null;let o=ji(n,t.cards);if(t.cards.every(s=>Number.isFinite(parseFloat(s)))){let s=n.map(parseFloat).filter(Number.isFinite);if(s.length===0)return {kind:"categorical",mode:vn(n,o),spread:Do(n)};let a=s.reduce((I,N)=>I+N,0)/s.length,d=[...s].toSorted((I,N)=>I-N),u=Math.floor(d.length/2),c=d.length%2===1?d[u]:(d[u-1]+d[u])/2,l=vn(n,o),p;if(new Set(n).size===1)p="unanimous";else {let I=n.map(T=>o(T)),N=Math.min(...I);p=Math.max(...I)-N<=1?"close":"spread";}return {kind:"numeric",mean:a,median:c,mode:l,spread:p}}return {kind:"categorical",mode:vn(n,o),spread:Do(n)}}function Cn(e){return e.replaceAll(/\|/g,"\\|")}function _i(e){return e.replaceAll(/\\/g,"\\\\").replaceAll(/]/g,"\\]")}function Fi(e){let n=(e.match(/`+/g)??[]).reduce((o,r)=>Math.max(o,r.length),0);return "`".repeat(n+1)}function bn(e){if(!e)return "";if(Ao(e))return ` ([${_i(e)}](<${e}>))`;let t=Fi(e);return ` (${t}${e}${t})`}function Vi(e){return e instanceof Map?e:new Map(Object.entries(e))}function Yi(e){let t=new Map;for(let r of e)t.set(r.id,r);function n(r){if(!r.parentRoundId)return r;let i=t.get(r.parentRoundId);return i?n(i):r}let o=new Map;for(let r of e){let i=n(r),s=o.get(i.id);s?s.push(r):o.set(i.id,[r]);}return o}function Mo(e,t){let n=new Map;e.scale.cards.forEach((a,d)=>n.set(a,d));let o=new Map,r=[];for(let[a,d]of Object.entries(e.votes)){let u=t.get(a)??a;if(W(d)){r.push(u);continue}let c=o.get(d);c?c.push(u):o.set(d,[u]);}let i=[...o.entries()].map(([a,d])=>({card:a,scaleIndex:n.get(a)??Number.MAX_SAFE_INTEGER,voters:[...d].toSorted().map(Cn)}));i.sort((a,d)=>{let u=d.voters.length-a.voters.length;return u!==0?u:a.scaleIndex-d.scaleIndex});let s=i.map(a=>`| ${Cn(a.card)} | ${a.voters.join(", ")} |`);return r.length>0&&s.push(`| Abstained | ${[...r].toSorted().map(Cn).join(", ")} |`),["| Vote | Voters |","|------|--------|",...s].join(`
|
|
3
|
-
`)}function
|
|
2
|
+
import aa from'yargs';import {hideBin}from'yargs/helpers';import nn,{useState,useEffect,useCallback,useMemo,useRef}from'react';import {render,useApp,useInput,Box,Text}from'ink';import*as $e from'yjs';import {Awareness}from'y-protocols/awareness';import {existsSync,readFileSync,writeFileSync,unlinkSync,mkdirSync,chmodSync}from'fs';import {homedir}from'os';import {join}from'path';import {randomUUID}from'crypto';import {createInterface}from'readline';import {WebsocketProvider}from'y-websocket';import as from'ws';import Or from'clipboardy';import {jsxs,jsx,Fragment}from'react/jsx-runtime';var Et="hnch_abstain";function K(e){return e===Et}var bi={"unknown-room":4001,"wrong-password":4002,"invalid-invite":4003,"expired-invite":4004,"invite-already-redeemed":4005,"room-full":4006,"malformed-credentials":4010},lo=new Map(Object.entries(bi).map(([e,t])=>[t,e]));function Ae(e){return e.role??"voter"}function Nt(e){return e.leftAt===void 0}var kt={id:"fibonacci",cards:["0","1","2","3","5","8","13","21"]},uo={id:"t-shirt",cards:["XS","S","M","L","XL"]},po={id:"powers-of-2",cards:["1","2","4","8","16","32","64"]},fo={id:"linear",cards:["1","2","3","4","5","6","7","8","9","10"]},mo={id:"risk",cards:["Low","Medium","High","Critical"]},ae={[kt.id]:kt,[uo.id]:uo,[po.id]:po,[fo.id]:fo,[mo.id]:mo},go={fibonacci:"Fibonacci","t-shirt":"T-shirt","powers-of-2":"Powers of 2",linear:"Linear (1\u201310)",risk:"Risk"};function ho(e){return e in go?go[e]:e.length===0?e:(e.startsWith("custom-")?e.slice(7):e).split("-").map(n=>n.length===0?n:n.charAt(0).toUpperCase()+n.slice(1)).join(" ")}function So(e,t,n){if(!e||e.status!=="voting"&&e.status!=="pending")return false;let o=new Set(t.filter(d=>Nt(d)&&n.has(d.id)&&Ae(d)!=="viewer").map(d=>d.id));if(o.size===0)return false;let r=Object.entries(e.votes).filter(([d])=>o.has(d)),i=r.filter(([,d])=>K(d)).length,s=r.length-i,a=o.size-i;return a<=0?false:s>=a}var Ze={"racing-green":{base:"#0B3D2E",soft:"rgba(11,61,46,0.14)",ink:"#fff",label:"Racing Green"},dijon:{base:"#C9A227",soft:"rgba(201,162,39,0.18)",ink:"#000",label:"Dijon"},blue:{base:"#0A84FF",soft:"rgba(10,132,255,0.14)",ink:"#fff",label:"Blue"},indigo:{base:"#5E5CE6",soft:"rgba(94,92,230,0.14)",ink:"#fff",label:"Indigo"},violet:{base:"#BF5AF2",soft:"rgba(191,90,242,0.14)",ink:"#fff",label:"Violet"},pink:{base:"#FF375F",soft:"rgba(255,55,95,0.14)",ink:"#fff",label:"Pink"},red:{base:"#FF453A",soft:"rgba(255,69,58,0.14)",ink:"#fff",label:"Red"},orange:{base:"#FF9F0A",soft:"rgba(255,159,10,0.16)",ink:"#000",label:"Orange"},amber:{base:"#FFD60A",soft:"rgba(255,214,10,0.18)",ink:"#000",label:"Amber"},green:{base:"#30D158",soft:"rgba(48,209,88,0.14)",ink:"#000",label:"Green"},teal:{base:"#40C8E0",soft:"rgba(64,200,224,0.14)",ink:"#000",label:"Teal"},graphite:{base:"#1C1C1E",soft:"rgba(28,28,30,0.10)",ink:"#fff",label:"Graphite"}};var at=["racing-green","dijon","blue","indigo","violet","pink","red","orange","amber","green","teal","graphite"],Ii=/^#[0-9a-fA-F]{6}$/;function Ai(e){return Object.hasOwn(Ze,e)}function Me(e){return e?Ai(e)?Ze[e].base:Ii.test(e)?e.toLowerCase():null:null}function xo(e){let t=5381;for(let o=0;o<e.length;o++)t=(t<<5)+t+e.charCodeAt(o)|0;let n=Math.abs(t)%at.length;return at[n]}var Re="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",Pt=Re.length,gn=Math.floor(Pt/2);function dt(e){let t=Re.indexOf(e);if(t===-1)throw new Error(`fractional-index: invalid character '${e}'`);return t}function wo(e,t){return e.length>=t?e:e+"0".repeat(t-e.length)}function Ri(e){let t=e.length-1;for(;t>0&&e[t]==="0";)t--;return e.slice(0,t+1)}function Ti(e,t){let n=e.length,o=Array.from({length:n+1}).fill(0),r=0;for(let a=n-1;a>=0;a--){let d=e[a]+t[a]+r;o[a+1]=d%Pt,r=Math.floor(d/Pt);}o[0]=r;let i=Array.from({length:n+1}).fill(0),s=0;for(let a=0;a<=n;a++){let d=o[a]+s*Pt;i[a]=Math.floor(d/2),s=d%2;}return i.slice(1)}function hn(e,t){let n=Re[gn];if(e===null&&t===null)return n+n;if(t===null)return e+n+n+n+n;if(e===null)return Ei(t);if(e>=t)throw new Error(`keyBetween: a must be < b (a='${e}', b='${t}')`);return ki(e,t)}function Ei(e){for(let t=e.length-1;t>=0;t--){let n=dt(e[t]);if(n>0)return e.slice(0,t)+Re[n-1]+Re[gn]}if(e.length>1)return e.slice(0,-1);throw new Error(`keyBetween: cannot generate key before '${e}' \u2014 use keyBetween(null, null) for the initial key`)}function ki(e,t){let n=Math.max(e.length,t.length),o=wo(e,n).split("").map(d=>dt(d)),r=wo(t,n).split("").map(d=>dt(d)),s=Ti(o,r).map(d=>Re[d]).join(""),a=Ri(s);return a>e&&a<t?a:s>e&&s<t?s:Ni(e,t)}function Ni(e,t){for(let n=0;n<t.length;n++){let o=n<e.length?dt(e[n]):0;if(dt(t[n])===o+1)return (n<e.length?e.slice(0,n+1):e+Re[0])+Re[gn]}throw new Error(`keyBetween: space exhausted between '${e}' and '${t}'`)}function Sn(e){let{revealedAt:t,skippedAt:n,discardedAt:o}=e;if(t===void 0&&n===void 0&&o===void 0)return null;let r=[];t!==void 0&&r.push({kind:"revealed",at:t}),n!==void 0&&r.push({kind:"skipped",at:n}),o!==void 0&&r.push({kind:"discarded",at:o});let i={revealed:0,skipped:1,discarded:2};return r.sort((s,a)=>s.at-a.at||i[s.kind]-i[a.kind]),r[0].kind}var yo="meta",lt="settings",vo="participants",Co="rounds",bo="agenda",Pi=["roomUuid","createdAt","createdBy","sessionEndedAt"],Di=["name","defaultScale","hostParticipantId"],Oi=["displayName","joinedAt","role","leftAt","removedBy","avatarColor"],Mi=["id","title","description","ticketId","state","source","externalId","sortKey","createdAt","consumedAt","consumedByRoundId"],$i=["id","title","description","ticketId","parentRoundId","scale","timerStartedAt","revealedAt","skippedAt","discardedAt","discardedBy","createdBy","createdAt","agendaItemId"];function Dt(e){return e.getMap(yo)}function Ot(e){return e.getMap(lt)}function Mt(e){return e.getMap(vo)}function xn(e){return e.getArray(Co)}function ct(e){return e.getArray(bo)}function ut(e,t){let n={};for(let o of t){let r=e.get(o);r!==void 0&&(n[o]=r);}return n}function Ui(e){return ut(Dt(e),Pi)}function Bi(e){return ut(Ot(e),Di)}function Hi(e){let t=Mt(e),n=[];return t.forEach((o,r)=>{let i=ut(o,Oi);n.push({id:r,...i});}),n.sort((o,r)=>o.joinedAt-r.joinedAt||o.id.localeCompare(r.id)),n}function Li(e){let t={};return e.forEach((n,o)=>{t[o]=n;}),t}function _i(e){let t=ut(e,$i),n=e.get("votes"),o=n?Li(n):{},r=Sn(t),{revealedAt:i,skippedAt:s,discardedAt:a,...d}=t,u=r??(t.timerStartedAt!==void 0?"voting":"pending"),c=r==="revealed"?i:r==="skipped"?s:r==="discarded"?a:void 0;return c===void 0?{...d,votes:o,status:u}:{...d,votes:o,status:u,terminalAt:c}}function ji(e){let t=xn(e),n=[];return t.forEach(o=>{n.push(_i(o));}),n}function Fi(e){return ut(e,Mi)}function Vi(e){let t=ct(e),n=[];return t.forEach(o=>{n.push(Fi(o));}),n.sort((o,r)=>o.sortKey.localeCompare(r.sortKey)),n}function _(e){return {meta:Ui(e),settings:Bi(e),participants:Hi(e),rounds:ji(e),agenda:Vi(e)}}function wn(e,t){if(Dt(e).has("roomUuid"))throw new Error("initDoc: doc already seeded");e.transact(()=>{let n=Dt(e);n.set("roomUuid",t.roomUuid),n.set("createdAt",t.createdAt),n.set("createdBy",t.participantId);let o=Ot(e);t.sessionName!==void 0&&o.set("name",t.sessionName),o.set("defaultScale",t.defaultScale),o.set("hostParticipantId",t.participantId);let r=new $e.Map;r.set("displayName",t.displayName),r.set("joinedAt",t.createdAt),t.avatarColor!==void 0&&r.set("avatarColor",t.avatarColor),Mt(e).set(t.participantId,r);});}function Ue(e,t){e.transact(()=>{let n=Mt(e),o=n.get(t.participantId),r=o??new $e.Map;r.set("displayName",t.displayName),o===void 0&&r.set("joinedAt",Date.now()),t.avatarColor!==void 0&&r.set("avatarColor",t.avatarColor),r.delete("leftAt"),r.delete("removedBy"),o===void 0&&n.set(t.participantId,r);});}function Be(e,t){e.transact(()=>{let n=Ot(e);for(let[o,r]of Object.entries(t))r===void 0?n.delete(o):n.set(o,r);});}function $t(e,t,n){e.transact(()=>{let o=Mt(e),r=o.get(t),i=r??new $e.Map;i.set("displayName",n.displayName),i.set("joinedAt",n.joinedAt),n.role!==void 0&&i.set("role",n.role),n.avatarColor!==void 0&&i.set("avatarColor",n.avatarColor),r===void 0&&o.set(t,i);});}function Ut(e,t){let n=t.scale??Ot(e).get("defaultScale");if(!n)throw new Error("appendRound: no scale (settings.defaultScale missing)");if(t.parentRoundId!==void 0){let o=He(e,t.parentRoundId);if(o!==void 0&&o.get("discardedAt")!==void 0)throw new Error(`appendRound: parentRoundId ${t.parentRoundId} points at a discarded round`)}return e.transact(()=>{let o=new $e.Map;o.set("id",t.id),o.set("createdAt",t.createdAt),o.set("createdBy",t.createdBy),o.set("scale",n),t.title!==void 0&&o.set("title",t.title),t.description!==void 0&&o.set("description",t.description),t.ticketId!==void 0&&o.set("ticketId",t.ticketId),t.parentRoundId!==void 0&&o.set("parentRoundId",t.parentRoundId),t.agendaItemId!==void 0&&o.set("agendaItemId",t.agendaItemId),o.set("timerStartedAt",t.createdAt),o.set("votes",new $e.Map),xn(e).push([o]);}),t.id}function yn(e,t,n){let o=He(e,t);if(!o)throw new Error(`patchRoundDescriptor: round ${t} not found`);e.transact(()=>{n.title!==void 0&&o.set("title",n.title),n.description!==void 0&&o.set("description",n.description);});}function He(e,t){let n=xn(e);for(let o=0;o<n.length;o+=1){let r=n.get(o);if(r.get("id")===t)return r}}function vn(e){return Sn({revealedAt:e.get("revealedAt"),skippedAt:e.get("skippedAt"),discardedAt:e.get("discardedAt")})}function Cn(e,t,n,o){let r=He(e,t);if(!r)throw new Error(`castVote: round ${t} not found`);r.get("revealedAt")===void 0&&e.transact(()=>{r.get("votes").set(n,o);});}function bn(e,t,n){let o=He(e,t);if(!o)throw new Error(`clearVote: round ${t} not found`);o.get("revealedAt")===void 0&&e.transact(()=>{o.get("votes").delete(n);});}function Io(e,t,n,o){let r=t.get("agendaItemId");if(r===void 0)return;let i=Rn(e,r);i!==void 0&&i.get("state")==="pending"&&(i.set("state","consumed"),i.set("consumedAt",o),i.set("consumedByRoundId",n));}function Ao(e,t,n){let o=He(e,t);if(!o)throw new Error(`revealRound: round ${t} not found`);let r=vn(o);if(r!==null)throw new Error(`revealRound: round ${t} already terminal (${r})`);e.transact(()=>{o.set("revealedAt",n),Io(e,o,t,n);});}function Ro(e,t,n){let o=He(e,t);if(!o)throw new Error(`skipRound: round ${t} not found`);let r=vn(o);if(r!==null)throw new Error(`skipRound: round ${t} already terminal (${r})`);e.transact(()=>{o.set("skippedAt",n),Io(e,o,t,n);});}function To(e,t,n,o){let r=He(e,t);if(!r)throw new Error(`discardRound: round ${t} not found`);let i=vn(r);if(i!==null)throw new Error(`discardRound: round ${t} already terminal (${i})`);e.transact(()=>{r.set("discardedAt",n),r.set("discardedBy",o);});}function In(e){e.transact(()=>{Dt(e).set("sessionEndedAt",Date.now());});}function W(e){let{rounds:t}=e;if(t.length===0)return null;for(let n=t.length-1;n>=0;n-=1){let o=t[n];if(o.status==="pending"||o.status==="voting")return o}for(let n=t.length-1;n>=0;n-=1){let o=t[n];if(o.status!=="discarded")return o}return null}function An(e){let t=Object.values(e.votes);return t.length<2?false:t.every(n=>n===t[0])}function Rn(e,t){let n=ct(e);for(let o=0;o<n.length;o++){let r=n.get(o);if(r.get("id")===t)return r}}function pt(e,t){if(!t.title?.trim()&&!t.ticketId?.trim())throw new Error("appendAgendaItem: at least one of {title, ticketId} is required");let n=crypto.randomUUID(),o=ct(e),r=null;o.forEach(s=>{if(s.get("state")==="pending"){let a=s.get("sortKey");a!==void 0&&(r===null||a>r)&&(r=a);}});let i=hn(r,null);return e.transact(()=>{let s=new $e.Map;s.set("id",n),s.set("state","pending"),s.set("source",t.source??"manual"),s.set("sortKey",i),s.set("createdAt",t.createdAt),t.title!==void 0&&s.set("title",t.title),t.description!==void 0&&s.set("description",t.description),t.ticketId!==void 0&&s.set("ticketId",t.ticketId),t.externalId!==void 0&&s.set("externalId",t.externalId),ct(e).push([s]);}),n}function Bt(e,t,n,o={}){let r=Rn(e,t);if(!r)throw new Error(`setAgendaItemState: item ${t} not found`);let i=r.get("state");if(!(i===n&&n==="consumed")){if(i!=="pending")throw new Error(`setAgendaItemState: invalid transition '${i}' \u2192 '${n}' for item ${t}`);e.transact(()=>{r.set("state",n),n==="consumed"&&(r.set("consumedAt",o.timestamp??Date.now()),o.consumedByRoundId!==void 0&&r.set("consumedByRoundId",o.consumedByRoundId));});}}function Tn(e,t,n,o){let r=Rn(e,t);if(!r)throw new Error(`reorderAgendaItem: item ${t} not found`);let i=r.get("state");if(i!=="pending")throw new Error(`reorderAgendaItem: item ${t} is ${i}; only pending items may be reordered`);let s=hn(n??null,o??null);e.transact(()=>{r.set("sortKey",s);});}function Le(e){for(let t of e.agenda)if(t.state==="pending")return t;return null}var Eo=5e3;function ko(e,t){let n=new Set;for(let o of e.participants)t.has(o.id)&&Nt(o)&&n.add(o.id);return n}function No(e,t,n){let o=e.settings.hostParticipantId;return o?ko(e,t).has(o)?{kind:"cancel"}:n.missingHostId!==o?{kind:"start-debounce",hostId:o}:{kind:"none"}:{kind:"none"}}function Po(e,t,n,o){let r=e.settings.hostParticipantId;if(!o||r!==o)return {promote:false};let i=ko(e,t);if(i.has(r))return {promote:false};let s=[...i].toSorted();if(s.length===0)return {promote:false};let a=s[0];return a!==n?{promote:false}:{promote:true,winner:a}}function Do(e){let t=Math.max(0,Math.floor(e/1e3)),n=Math.floor(t/60),o=t%60;return `${n}:${o.toString().padStart(2,"0")}`}function Oo(e){try{let t=new URL(e);return t.protocol==="http:"||t.protocol==="https:"}catch{return false}}function En(e){if(e===null||typeof e!="object"||Array.isArray(e))return {version:2,entries:{}};let t=e;if(t.version===2&&$o(t.entries)){let n=t.entries,o={};for(let[r,i]of Object.entries(n)){let s=Yi(i);s!==null&&(o[r]=s);}return {version:2,entries:o}}if(typeof t.roomCode=="string"&&typeof t.roomUuid=="string"&&typeof t.lastSeenAt=="number"){let n={roomCode:t.roomCode,roomUuid:t.roomUuid,lastSeenAt:t.lastSeenAt,...typeof t.passwordHash=="string"?{passwordHash:t.passwordHash}:{}};return {version:2,entries:{[n.roomUuid]:n}}}return {version:2,entries:{}}}function Mo(e,t,n=864e5){let o={};for(let[r,i]of Object.entries(e.entries))t-i.lastSeenAt>n||(i.lastSeenAt>t?o[r]={...i,lastSeenAt:t}:o[r]=i);return {version:2,entries:o}}function $o(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function Yi(e){if(!$o(e))return null;let t=e;return typeof t.roomCode!="string"||typeof t.roomUuid!="string"||typeof t.lastSeenAt!="number"?null:{roomCode:t.roomCode,roomUuid:t.roomUuid,lastSeenAt:t.lastSeenAt,...typeof t.passwordHash=="string"?{passwordHash:t.passwordHash}:{}}}function Uo(e,t){let n=t.filter(p=>p.status!=="discarded"),o=new Map;for(let p of n)o.set(p.id,p);let r=o.get(e);if(r===void 0||r.parentRoundId===void 0)return null;let i=new Set([r.id]),s=r,a=1;for(;s.parentRoundId!==void 0;){let p=o.get(s.parentRoundId);if(p===void 0||i.has(p.id))return null;i.add(p.id),s=p,a+=1;}let d=s,u=new Map;for(let p of n){if(p.parentRoundId===void 0)continue;let A=u.get(p.parentRoundId);A===void 0?u.set(p.parentRoundId,[p]):A.push(p);}let c=0,l=[d];for(;l.length>0;){let p=l.shift();c+=1;let A=u.get(p.id);A!==void 0&&l.push(...A);}return {chainRoot:d,depth:a,total:c}}var Bo="PBKDF2",Ki="SHA-256",Ho=new TextEncoder;function Ji(e){return Array.from(new Uint8Array(e)).map(t=>t.toString(16).padStart(2,"0")).join("")}async function _e(e,t){let n=await crypto.subtle.importKey("raw",Ho.encode(e),Bo,false,["deriveBits"]),o=await crypto.subtle.deriveBits({name:Bo,salt:Ho.encode(t),iterations:1e5,hash:Ki},n,256);return Ji(o)}var Lo="ABCDEFGHJKMNPQRSTUVWXYZ23456789";if(Lo.length!==31)throw new Error(`Room code alphabet must be 31 characters, got ${Lo.length}`);function kn(e){return e.trim().replaceAll(/-/g,"").toUpperCase()}function _o(e,t=true){let n=kn(e);return !t||n.length!==6?n:`${n.slice(0,3)}-${n.slice(3)}`}function de(e){return e==="revealed"||e==="skipped"||e==="discarded"}function Ht(e){return !de(e)}function Nn(e){let t=W(_(e));return t?Ht(t.status)?{round:t}:{applied:false,reason:"already-terminal"}:{applied:false,reason:"no-current-round"}}function Pn(e,t=Date.now){let n=Nn(e);if("applied"in n)return n;let o=t();return Ao(e,n.round.id,o),{applied:true,at:o}}function jo(e,t=Date.now){let n=Nn(e);if("applied"in n)return n;let o=t();return Ro(e,n.round.id,o),{applied:true,at:o}}function Fo(e,t,n=Date.now){let o=Nn(e);if("applied"in o)return o;let r=n();return To(e,o.round.id,r,t),{applied:true,at:r}}function Vo(e){let t=new Set(e).size;return t===1?"unanimous":t===2?"close":"spread"}function Gi(e,t){let n=new Map;t.forEach((i,s)=>n.set(i,s));let o=[...new Set(e.filter(i=>!n.has(i)))].toSorted(),r=new Map;return o.forEach((i,s)=>r.set(i,t.length+s)),i=>n.get(i)??r.get(i)??Number.MAX_SAFE_INTEGER}function Dn(e,t){let n=new Map;for(let s of e)n.set(s,(n.get(s)??0)+1);let o=null,r=0,i=[...n.keys()].toSorted((s,a)=>t(s)-t(a));for(let s of i){let a=n.get(s);a>r&&(r=a,o=s);}return o}function Yo(e,t){let n=Object.values(e);if(n.length===0)return null;let o=Gi(n,t.cards);if(t.cards.every(s=>Number.isFinite(parseFloat(s)))){let s=n.map(parseFloat).filter(Number.isFinite);if(s.length===0)return {kind:"categorical",mode:Dn(n,o),spread:Vo(n)};let a=s.reduce((A,N)=>A+N,0)/s.length,d=[...s].toSorted((A,N)=>A-N),u=Math.floor(d.length/2),c=d.length%2===1?d[u]:(d[u-1]+d[u])/2,l=Dn(n,o),p;if(new Set(n).size===1)p="unanimous";else {let A=n.map(T=>o(T)),N=Math.min(...A);p=Math.max(...A)-N<=1?"close":"spread";}return {kind:"numeric",mean:a,median:c,mode:l,spread:p}}return {kind:"categorical",mode:Dn(n,o),spread:Vo(n)}}function On(e){return e.replaceAll(/\|/g,"\\|")}function Wi(e){return e.replaceAll(/\\/g,"\\\\").replaceAll(/]/g,"\\]")}function qi(e){let n=(e.match(/`+/g)??[]).reduce((o,r)=>Math.max(o,r.length),0);return "`".repeat(n+1)}function Mn(e){if(!e)return "";if(Oo(e))return ` ([${Wi(e)}](<${e}>))`;let t=qi(e);return ` (${t}${e}${t})`}function zi(e){return e instanceof Map?e:new Map(Object.entries(e))}function Xi(e){let t=new Map;for(let r of e)t.set(r.id,r);function n(r){if(!r.parentRoundId)return r;let i=t.get(r.parentRoundId);return i?n(i):r}let o=new Map;for(let r of e){let i=n(r),s=o.get(i.id);s?s.push(r):o.set(i.id,[r]);}return o}function Ko(e,t){let n=new Map;e.scale.cards.forEach((a,d)=>n.set(a,d));let o=new Map,r=[];for(let[a,d]of Object.entries(e.votes)){let u=t.get(a)??a;if(K(d)){r.push(u);continue}let c=o.get(d);c?c.push(u):o.set(d,[u]);}let i=[...o.entries()].map(([a,d])=>({card:a,scaleIndex:n.get(a)??Number.MAX_SAFE_INTEGER,voters:[...d].toSorted().map(On)}));i.sort((a,d)=>{let u=d.voters.length-a.voters.length;return u!==0?u:a.scaleIndex-d.scaleIndex});let s=i.map(a=>`| ${On(a.card)} | ${a.voters.join(", ")} |`);return r.length>0&&s.push(`| Abstained | ${[...r].toSorted().map(On).join(", ")} |`),["| Vote | Voters |","|------|--------|",...s].join(`
|
|
3
|
+
`)}function Jo(e){let t=Object.fromEntries(Object.entries(e.votes).filter(([,i])=>!K(i))),n=Yo(t,e.scale),o=e.timerStartedAt!=null&&e.status==="revealed"&&e.terminalAt!=null?Do(e.terminalAt-e.timerStartedAt):null,r=[];return n?.kind==="numeric"?r.push(`Avg ${n.mean.toFixed(1)} \xB7 Med ${n.median}`):n?.kind==="categorical"&&r.push(`Most common: ${n.mode}`),o!=null&&r.push(`Elapsed ${o}`),r.join(" \xB7 ")}function Go(e){let{rounds:t}=e,n=zi(e.participants),o=new Map;for(let[c,l]of n)o.set(c,l.displayName);let r=t.filter(c=>c.status==="revealed");if(r.length===0)return "";let i=new Map;t.forEach((c,l)=>i.set(c.id,l+1));let s=Xi(r),a=new Set,d=[];for(let c of r)for(let[l,p]of s)if(p.includes(c)&&!a.has(l)){a.add(l),d.push(l);break}let u=[];for(let c of d){let l=s.get(c),p=l.find(h=>h.id===c),A=l.filter(h=>h.id!==c),N=i.get(p.id)??0,R=p.title?`## Round ${N} \u2014 ${p.title}${Mn(p.ticketId)}`:`## Round ${N}${Mn(p.ticketId)}`,T=Ko(p,o),U=Jo(p),f=U?`${R}
|
|
4
4
|
|
|
5
5
|
${T}
|
|
6
6
|
|
|
7
7
|
${U}`:`${R}
|
|
8
8
|
|
|
9
|
-
${T}`;u.push(f);for(let h of
|
|
9
|
+
${T}`;u.push(f);for(let h of A){let y=`### Re-vote ${i.get(h.id)??0}${Mn(h.ticketId)}`,O=Ko(h,o),C=Jo(h),M=C?`${y}
|
|
10
10
|
|
|
11
11
|
${O}
|
|
12
12
|
|
|
@@ -15,11 +15,11 @@ ${C}`:`${y}
|
|
|
15
15
|
${O}`;u.push(M);}}return u.join(`
|
|
16
16
|
|
|
17
17
|
`)+`
|
|
18
|
-
`}function
|
|
19
|
-
`,"utf-8");}async function
|
|
20
|
-
`,"utf-8");}async function
|
|
21
|
-
`);}function Ht(e){let t=Date.now();if(!existsSync(je()))return [];let n;try{n=JSON.parse(readFileSync(je(),"utf-8"));}catch{return []}let o=xn(n),r=Io(o,t),i=Object.values(r.entries);return i.length===0?(En(),[]):i.toSorted((s,a)=>a.lastSeenAt-s.lastSeenAt)}function ss(e,t){return e!==void 0?{passwordHash:e}:t!==void 0?{passwordHash:t}:{}}function Pn(e){let t=Date.now(),n=kn(),o=n[e.roomUuid];n[e.roomUuid]={roomCode:e.roomCode,roomUuid:e.roomUuid,lastSeenAt:e.lastSeenAt??t,...ss(e.passwordHash,o?.passwordHash)};let r=Object.keys(n);if(r.length>5){let i=r.toSorted((s,a)=>(n[s]?.lastSeenAt??0)-(n[a]?.lastSeenAt??0)).slice(0,r.length-5);for(let s of i)delete n[s];}Nn(n);}function pt(e){if(!existsSync(je()))return;let t=kn();if(delete t[e],Object.keys(t).length===0){En();return}Nn(t);}function as(){En();}function Dn(e){if(!existsSync(je()))return;let t=kn(),n=t[e];if(!n)return;let{passwordHash:o,...r}=n;t[e]=r,Nn(t);}function On(e){Pn(e);}function Se(){as();}async function Lt(e){let t=true;try{await e.clearLastSession();}catch(n){t=false,e.logger.error(`Failed to clear cached session: ${n instanceof Error?n.message:String(n)}`);}return t?e.logger.error("Session expired (room no longer exists). Cached session cleared."):e.logger.error("Session expired. Could not delete ~/.config/hnch/last-session.json \u2014 please remove it manually."),e.exit(1)}function jt(e){let t=e.doc.getMap("meta"),n=null,o=false;function r(){if(o)return;let i=t.get("sessionEndedAt");if(i==null||i===n)return;n=i;let s=t.get("createdBy"),a=s===e.localParticipantId,d=e.doc.getMap("participants"),u=e.doc.getMap("settings").get("hostParticipantId")??s,c="host";if(u){let p=d.get(u)?.get("displayName");typeof p=="string"&&p.length>0&&(c=p);}setImmediate(()=>{o||e.onEnded({isLocal:a,hostName:c,timestamp:i});});}return t.observe(r),r(),()=>{o=true,t.unobserve(r);}}var ds="@xauyxau/hnch";function _t(e){return Po(e)}function Ft(e){return `${process.env.HNCH_SHARE_ORIGIN??"https://hnch.dev"}/join?code=${e}`}function Vt(e){return `npx ${ds} join ${e}`}function Mn(e){let t=e.trim();return t===""?void 0:t}function Yt(e){return e?{title:e.title??"",ticketId:e.ticketId??"",agendaItemId:e.id}:{title:"",ticketId:"",agendaItemId:void 0}}function Xo(e,t,n){return [e,Mn(t),n]}var cs={connecting:"yellow",connected:"green",disconnected:"red"};function er({roomCode:e,sessionName:t,status:n,isHost:o}){let r=t?`${e} \xB7 ${t}`:e;return jsxs(Box,{borderStyle:"single",borderColor:"gray",paddingX:1,justifyContent:"space-between",children:[jsxs(Text,{bold:true,children:["hnch \xB7 ",r]}),jsxs(Box,{gap:2,children:[o&&jsx(Text,{color:"yellow",children:"[host]"}),jsx(Text,{color:cs[n],children:n})]})]})}function me({items:e,onSelect:t,onClose:n,title:o}){if(e.length===0)return jsxs(Box,{flexDirection:"column",gap:1,children:[o&&jsx(Text,{bold:true,children:o}),jsx(Text,{dimColor:true,children:"(no items)"})]});let r=e.findIndex(a=>!a.disabled),[i,s]=useState(Math.max(r,0));return useInput((a,d)=>{if(d.upArrow)s(u=>{let c=(u-1+e.length)%e.length,l=0;for(;e[c]?.disabled&&l<e.length;)c=(c-1+e.length)%e.length,l++;return c});else if(d.downArrow)s(u=>{let c=(u+1)%e.length,l=0;for(;e[c]?.disabled&&l<e.length;)c=(c+1)%e.length,l++;return c});else if(d.return){let u=e[i];u&&!u.disabled&&t(u.value);}else d.escape&&n?.();}),jsxs(Box,{flexDirection:"column",gap:1,children:[o&&jsx(Text,{bold:true,children:o}),jsx(Box,{flexDirection:"column",children:e.map((a,d)=>{let u=d===i,c=a.disabled??false;return jsxs(Box,{gap:1,children:[jsx(Text,{...u&&{color:"cyan"},dimColor:c,children:u?">":" "}),jsx(Text,{bold:u,dimColor:c,children:a.label}),a.detail&&jsx(Text,{dimColor:true,children:a.detail})]},a.value)})}),jsx(Text,{dimColor:true,children:"\u2191\u2193 select \u23CE confirm esc close"})]})}function F({value:e,onChange:t,onSubmit:n,onCancel:o,placeholder:r,isActive:i=true,mask:s=false}){useInput((c,l)=>{l.escape?o?.():l.return?n(e):l.backspace||l.delete?t(e.slice(0,-1)):c&&!l.ctrl&&!l.meta&&t(e+c);},{isActive:i});let a=s&&e.length>0?"*".repeat(e.length):e,d=a.length>0?a:r??"",u=e.length===0&&r!==void 0;return jsxs(Text,{children:[jsx(Text,{dimColor:u,children:d}),jsx(Text,{inverse:true,children:" "})]})}function rr({mode:e,password:t,onModeChange:n,onPasswordChange:o,onClose:r}){let[i,s]=useState(e==="open"?0:1),[a,d]=useState(false);return useEffect(()=>{s(e==="open"?0:1);},[e]),useInput((u,c)=>{if(c.leftArrow)s(l=>Math.max(0,l-1));else if(c.rightArrow)s(l=>Math.min(1,l+1));else if(c.return){let l=i===0?"open":"password";l!==e&&n(l),l==="password"&&d(true);}else c.escape&&r?.();},{isActive:!a}),jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Box,{gap:1,children:["open","password"].map((u,c)=>{let l=c===i,p=u===e,I=u==="open"?"Open":"Password";return jsx(Text,{inverse:l,bold:p,...p&&{color:"cyan"},children:p?`[${I}]`:` ${I} `},u)})}),e==="password"&&jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{children:"Password: "}),jsx(F,{value:t,onChange:o,onSubmit:()=>d(false),onCancel:()=>d(false),placeholder:"(required to join)",isActive:a,mask:true}),!a&&jsx(Text,{dimColor:true,children:"\u23CE edit \u2190 \u2192 switch mode esc close"}),a&&jsx(Text,{dimColor:true,children:"\u23CE done esc cancel"})]}),e==="open"&&jsx(Text,{dimColor:true,children:"\u2190\u2192 toggle \u23CE confirm esc close"})]})}function ar({scaleId:e,cards:t,disabledIndices:n,onOverrideChange:o,onClose:r}){let i=useMemo(()=>new Set(n),[n]),[s,a]=useState(0),d=u=>{let c=new Set(i);if(c.has(u))c.delete(u);else {if(c.size>=t.length-1)return;c.add(u);}let l=Array.from(c).toSorted((p,I)=>p-I);o(e,l);};return useInput((u,c)=>{c.leftArrow?a(l=>Math.max(0,l-1)):c.rightArrow?a(l=>Math.min(t.length-1,l+1)):u===" "?d(s):(c.return||c.escape)&&r();}),jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Box,{gap:1,children:t.map((u,c)=>{let l=c===s,p=i.has(c);return jsx(Text,{inverse:l,bold:!p,...!p&&{color:"cyan"},strikethrough:p,dimColor:p,children:u},u)})}),jsx(Text,{dimColor:true,children:" \u2190\u2192 navigate space toggle \u23CE/esc done"})]})}function Fn({initialName:e="",initialCards:t=[],onSave:n,onCancel:o}){let r=e.length>0,[i,s]=useState(e),[a,d]=useState(t.length>0?t:[""]),[u,c]=useState(0),[l,p]=useState("editing-name"),[I,N]=useState(""),R=()=>{let f=i.trim();if(f.length===0||f.length>40){N("Name must be 1-40 characters");return}s(f),N(""),p("editing-cards");},T=()=>{let f=i.trim();if(f.length===0||f.length>40){N("Name must be 1-40 characters");return}let h=a.map(y=>y.trim()).filter(y=>y.length>0),b=Array.from(new Set(h));if(b.length<2){N("Need at least 2 unique non-empty cards");return}N(""),n(f,b);};return useInput((f,h)=>{if(l==="editing-cards"){if(h.leftArrow)c(b=>Math.max(0,b-1));else if(h.rightArrow)c(b=>{let y=b+1;return y>=a.length&&a.length<25?(d(O=>[...O,""]),y):Math.min(y,a.length-1)});else if(h.return)T();else if(h.escape)o();else if(h.tab)p("editing-name");else if(h.backspace){let b=a[u]||"";if(b.length===0){if(a.length>2){let y=a.filter((O,C)=>C!==u);d(y),c(Math.max(0,u-1));}}else {let y=[...a];y[u]=b.slice(0,-1),d(y);}}else if(f&&!h.ctrl&&!h.meta){let b=a[u]||"";if(b.length<10){let y=[...a];y[u]=b+f,d(y);}}}},{isActive:l==="editing-cards"}),jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:r?"\u2500\u2500 Edit Custom Scale \u2500\u2500":"\u2500\u2500 Create Custom Scale \u2500\u2500"}),jsxs(Box,{flexDirection:"column",gap:0,children:[jsx(Text,{children:"Name:"}),jsx(F,{value:i,onChange:s,onSubmit:R,onCancel:o,placeholder:"Scale name",isActive:l==="editing-name"})]}),l==="editing-cards"&&jsxs(Box,{flexDirection:"column",gap:0,children:[jsx(Text,{children:"Cards:"}),jsx(Box,{gap:1,flexWrap:"wrap",children:a.map((f,h)=>{let b=h===u;return jsx(Text,{inverse:b,...!b&&{color:"cyan"},children:f.length>0?f:"\xB7"},h)})})]}),I&&jsx(Text,{color:"red",children:I}),jsx(Text,{dimColor:true,children:l==="editing-name"?"\u23CE next esc cancel":"\u2190\u2192 navigate typing adds card bsp delete \u23CE save tab name esc cancel"})]})}function Kt({scales:e,selectedScaleId:t,presetOverrides:n,customScales:o=[],onSelect:r,onOverrideChange:i,onCustomScaleCreate:s,onCustomScaleEdit:a,onCustomScaleDelete:d,onClose:u,showNoneOption:c=false}){let[l,p]=useState(0),[I,N]=useState(null),[R,T]=useState("browsing"),[U,f]=useState(null),[h,b]=useState(null),y=s?[...e,{id:"__create-custom__",cards:[]}]:e,O=y.length;if(useInput((C,M)=>{if(R==="browsing"){if(M.escape){u();return}if(O===0)return;if(M.upArrow)p(A=>(A-1+O)%O);else if(M.downArrow)p(A=>(A+1)%O);else if(M.return){let A=y[l];if(!A)return;if(A.id==="__create-custom__"){T("creating");return}A.id in de?N(I===A.id?null:A.id):r(A.id);}else if(C===" "){let A=y[l];A&&A.id!=="__create-custom__"&&r(A.id);}else if(C==="e"||C==="E"){let A=y[l];a&&A?.id.startsWith("custom-")&&(f(A.id),T("editing"));}else if(C==="d"||C==="D"){let A=y[l];d&&A?.id.startsWith("custom-")&&(b(A.id),T("confirming-delete"));}}else R==="confirming-delete"&&(C==="y"||C==="Y"?(h&&d&&d(h),b(null),T("browsing")):(C==="n"||C==="N"||M.escape)&&(b(null),T("browsing")));},{isActive:R==="browsing"&&I===null||R==="confirming-delete"}),R==="creating")return jsx(Fn,{onSave:(C,M)=>{s&&s(C,M),T("browsing");},onCancel:()=>T("browsing")});if(R==="editing"&&U){let C=o?.find(A=>A.id===U);if(e.find(A=>A.id===U)&&C)return jsx(Fn,{initialName:C.label,initialCards:C.cards,onSave:(A,P)=>{a&&a(U,A,P),f(null),T("browsing");},onCancel:()=>{f(null),T("browsing");}})}if(R==="confirming-delete"&&h){let C=y.find(A=>A.id===h),M=C?He(C.id,o):"Unknown";return jsxs(Box,{flexDirection:"column",gap:1,children:[jsxs(Text,{children:["Delete ",M,"? "]}),jsx(Text,{children:"[y] yes [n] no esc cancel"})]})}return y.length===0?jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{dimColor:true,children:"(no scales available)"}),jsx(Text,{dimColor:true,children:"esc back"})]}):jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Box,{flexDirection:"column",children:y.map((C,M)=>{let A=M===l,P=C.id===t,ue=I===C.id,ie=C.id in de,se=C.id==="__create-custom__",Y=C.cards.join(", "),X=c&&C.id==="",Q=X?"(none)":se?"[+ Create custom scale]":He(C.id,o);return jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{gap:1,children:[jsx(Text,{...A&&{color:"cyan"},children:A?">":" "}),jsx(Text,{bold:A,children:Q}),!X&&!se&&jsx(Text,{dimColor:true,children:Y}),P&&jsx(Text,{color:"cyan",children:"[current]"})]}),ue&&!X&&!se&&jsx(Box,{paddingLeft:2,children:ie?jsx(ar,{scaleId:C.id,cards:de[C.id]?.cards??[],disabledIndices:n?.[C.id]??[],onOverrideChange:i,onClose:()=>N(null)}):null})]},C.id||"none")})}),jsx(Text,{dimColor:true,children:(()=>{let C=l<y.length?y[l]:null;return C?.id.startsWith("custom-")?`\u2191\u2193 navigate space select${a?" [e] edit":""}${d?" [d] delete":""} esc back`:C&&C.id in de?"\u2191\u2193 navigate \u23CE customize space select esc back":"\u2191\u2193 navigate \u23CE/space select esc back"})()})]})}function bs(e,t){return t?[...e]:e.filter(n=>n.value==="display-name")}function dr({sessionName:e,displayName:t,currentScale:n,accessMode:o,presetOverrides:r,customScales:i,isHost:s=true,onChangeName:a,onChangeScale:d,onChangeDisplayName:u,onChangeAccess:c,onClose:l}){let[p,I]=useState(r??{}),N=useMemo(()=>Ut(p,i),[p,i]),[R,T]=useState("main-menu"),[U,f]=useState(e??""),[h,b]=useState(t),[y,O]=useState(o==="password"?"password":"open"),[C,M]=useState(""),[A,P]=useState(false),ue=[{label:"Room name",value:"room-name",detail:`[${e??"(none)"}]`},{label:"Scale",value:"scale",detail:`[${He(n.id,i)}]`},{label:"Access",value:"access",detail:`[${o==="open"?"Open":"Password"}]`},{label:"Display name",value:"display-name",detail:`[${t}]`}],ie=bs(ue,s);function se(m){!s&&m!=="display-name"||(m==="room-name"?(f(e??""),T("editing-room-name")):m==="scale"?T("picking-scale"):m==="access"?T("picking-access"):m==="display-name"&&(b(t),T("editing-display-name")));}function Y(m){let w=m.trim()===""?void 0:m.trim();a(w),T("main-menu");}function X(m){let w=m.trim();w.length>0&&(u(w),process.nextTick(()=>V({displayName:w}))),T("main-menu");}function Q(m){let w=N.find(E=>E.id===m);w&&d(w),T("main-menu");}function ve(m,w){let E={...p};w.length===0?delete E[m]:E[m]=w,I(E),V({presetOverrides:Object.keys(E).length>0?E:void 0});}async function ge(m,w){P(true);try{await c(m,w),O(m),M(m==="password"?w??"":"");}catch(E){console.error(`Failed to update access: ${E}`);}finally{P(false),T("main-menu");}}return R==="main-menu"?jsx(me,{title:"\u2500\u2500 Settings \u2500\u2500",items:ie,onSelect:se,onClose:l}):R==="editing-room-name"?jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Settings \u2500\u2500"}),jsx(Text,{children:"Room name: "}),jsx(F,{value:U,onChange:f,onSubmit:Y,onCancel:()=>T("main-menu"),placeholder:"(leave empty to remove)",isActive:true}),jsx(Text,{dimColor:true,children:"\u23CE confirm esc back"})]}):R==="editing-display-name"?jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Settings \u2500\u2500"}),jsx(Text,{children:"Display name: "}),jsx(F,{value:h,onChange:b,onSubmit:X,onCancel:()=>T("main-menu"),placeholder:"(required)",isActive:true}),jsx(Text,{dimColor:true,children:"\u23CE confirm esc back"})]}):R==="picking-scale"?jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Settings \u2500\u2500"}),jsx(Kt,{scales:N,selectedScaleId:n.id,presetOverrides:p,onSelect:Q,onOverrideChange:ve,onClose:()=>T("main-menu")})]}):R==="picking-access"?jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Settings \u2500\u2500"}),A&&jsx(Text,{dimColor:true,children:"Updating access..."}),!A&&jsx(rr,{mode:y,password:C,onModeChange:m=>{m==="open"&&ge("open");},onPasswordChange:M,onClose:()=>T("main-menu")})]}):jsx(Box,{})}function zt({participants:e,onlineIds:t,hostId:n,votes:o,revealed:r,participantId:i}){return jsxs(Box,{flexDirection:"column",children:[jsxs(Text,{bold:true,children:["Participants (",e.length,")"]}),e.map(s=>{let a=t.has(s.id),d=a?"\u25CF":"\u25CB",u=a?"green":"gray",c=s.id===n,l=Ie(s)==="viewer",p=s.id===i,I=s.id in o,N=l?" (viewer)":r?o[s.id]?` \u2192 ${o[s.id]}`:"":I?" \u2713":" \xB7",R=p&&!l&&!(r&&o[s.id]);return jsxs(Box,{gap:1,children:[jsx(Text,{color:u,children:d}),jsxs(Text,{children:[s.displayName,c?" (host)":""]}),R?jsx(Text,{color:"cyan",children:"(voter)"}):jsx(Text,{color:l?"gray":I?"green":"gray",children:N})]},s.id)})]})}var As=[{label:"End session for everyone",value:"end-session",detail:"Disconnects all participants. Cannot be undone."}];function lr({onPick:e,onClose:t}){return jsx(me,{title:"Host Actions",items:As,onSelect:e,onClose:t})}function Xt({roomCode:e,onPick:t,onClose:n}){let o=[{label:"Copy code",value:"code",detail:_t(e)},{label:"Copy share link",value:"url",detail:Ft(e)},{label:"Copy npx command",value:"npx",detail:Vt(e)}];return jsx(me,{title:"Share",items:o,onSelect:r=>t(r),onClose:n})}function Ts(e){let t=e.rounds.filter(o=>_(o)!==null),n=Object.fromEntries(e.participants.map(o=>[o.id,o]));return Uo({rounds:t,participants:n})}async function ur(e,t,n){let o=Ts(e);try{await t(o),n("Results copied to clipboard");}catch{n("Clipboard write failed");}}function pr(e,t,n){let o=To(e.id,n);return o===null?`Round ${t}`:`Round ${o.depth}/${o.total} [re-vote]`}function fr(e,t,n){let o=pr(e,t,n),r=e.title?` \u2014 ${e.title}`:"",i=e.ticketId?` [${e.ticketId}]`:"",s=_(e)==="skipped"?" \u2014 Skipped":" \u2014 Results";return `${o}${r}${i}${s}`}function mr(e){let t=Object.values(e).filter(c=>!W(c)).map(c=>parseFloat(c)).filter(c=>!isNaN(c)).toSorted((c,l)=>c-l);if(t.length===0)return {average:"-",median:"-",agreement:"-"};let o=t.reduce((c,l)=>c+l,0)/t.length,r=Math.floor(t.length/2),i=t.length%2===0?(t[r-1]+t[r])/2:t[r],s=Object.values(e).filter(c=>!W(c)),a=new Map;for(let c of s)a.set(c,(a.get(c)??0)+1);let d=Math.max(...a.values()),u=s.length>0?Math.round(d/s.length*100):0;return {average:o.toFixed(1),median:i.toFixed(1),agreement:`${u}%`}}function Yn(e,t){let n=Math.floor((t-e)/1e3),o=Math.floor(n/60),r=n%60;return `${o}:${r.toString().padStart(2,"0")}`}function gr(e,t,n=[]){let o=pr(e,t,n);if(_(e)==="skipped"){let l=e.title?` ${e.title}`:"",p=e.ticketId?` [${e.ticketId}]`:"";return `${o}:${l}${p} \u2014 Skipped`}let r=new Map;for(let l of Object.values(e.votes))W(l)||r.set(l,(r.get(l)??0)+1);let i=[...r.entries()].toSorted((l,p)=>p[1]-l[1]||l[0].localeCompare(p[0])).map(([l,p])=>`${l}\xD7${p}`).join(", "),s=Object.values(e.votes).filter(W).length,a=s>0?` (${s} abstained)`:"",d=e.title?` ${e.title}`:"",u=e.ticketId?` [${e.ticketId}]`:"",c=e.timerStartedAt!==void 0&&e.revealedAt!==void 0?` \u2014 ${Yn(e.timerStartedAt,e.revealedAt)}`:"";return `${o}:${d}${u} \u2014 ${i||"(no votes)"}${a}${c}`}function hr({projection:e,onlineIds:t,isHost:n,participantId:o,rounds:r,currentRound:i,settingsOpen:s,onStartRound:a,onNewRound:d,onRevote:u,onOpenSettings:c,onHandoffHost:l,onEndSession:p,onShare:I,shareOpen:N,onSetShareOpen:R,roomCode:T,confirmingQuit:U,myRole:f,onToggleRole:h,roundTitlePromptActive:b,roundTitleInput:y,onRoundTitleChange:O,onRoundTitleSubmit:C,onRoundTitleCancel:M,roundTicketIdPromptActive:A,roundTicketIdInput:P,onRoundTicketIdChange:ue,onRoundTicketIdSubmit:ie,onRoundTicketIdCancel:se,descriptorPromptActive:Y,descriptorInput:X,onDescriptorChange:Q,onDescriptorSubmit:ve,onDescriptorCancel:ge,onEditDescriptor:m,canExport:w,onExportResults:E,onAgendaAdd:J,agendaAddPromptActive:pe,agendaAddTitleInput:rt,onAgendaAddTitleChange:an,onAgendaAddTitleSubmit:We,onAgendaAddTitleCancel:vt,agendaAddTicketIdPromptActive:Ce,agendaAddTicketIdInput:dn,onAgendaAddTicketIdChange:Ke,onAgendaAddTicketIdSubmit:Ge,onAgendaAddTicketIdCancel:Pe}){let[Z,ee]=Qt.useState("idle"),[he,be]=Qt.useState(null),[it,ae]=Qt.useState(false),[fe,De]=Qt.useState(false);useEffect(()=>{n||(ee("idle"),be(null),ae(false),De(false));},[n]),useInput(x=>{if(x==="c"||x==="C"){R(true);return}if(x==="w"||x==="W"){h();return}if((x==="x"||x==="X")&&w){E();return}if(n){if(x==="a"||x==="A"){J();return}(x==="e"||x==="E")&&c(),(x==="s"||x==="S")&&a(),(x==="h"||x==="H")&&ee("picking"),(x==="m"||x==="M")&&ae(true),i!==null&&_(i)!==null&&((x==="n"||x==="N")&&d(),(x==="v"||x==="V")&&_(i)!=="skipped"&&u(),(x==="t"||x==="T")&&m());}},{isActive:!s&&!U&&Z==="idle"&&!b&&!A&&!it&&!fe&&!N&&!Y&&!pe&&!Ce}),useInput((x,te)=>{x==="y"||x==="Y"?(p(),De(false)):(x==="n"||x==="N"||te.escape)&&De(false);},{isActive:fe});let Ae=e.participants.filter(x=>x.id!==o&&t.has(x.id));useInput(x=>{if(Z==="picking"){let te=parseInt(x,10);!isNaN(te)&&te>=1&&te<=Ae.length?(be(Ae[te-1].id),ee("confirming")):(x==="Escape"||x==="q"||x==="Q")&&ee("idle");}},{isActive:Z==="picking"}),useInput(x=>{Z==="confirming"&&he&&(x==="y"||x==="Y"?(l(he),ee("idle"),be(null)):(x==="n"||x==="N"||x==="Escape")&&(ee("idle"),be(null)));},{isActive:Z==="confirming"});let Oe=r.length>0,Ct=r.filter(x=>_(x)!==null),st=i!==null?Ct.slice(0,-1):Ct;return it?jsx(lr,{onPick:x=>{ae(false),x==="end-session"&&De(true);},onClose:()=>ae(false)}):N?jsx(Xt,{roomCode:T,onPick:x=>{R(false),I(x);},onClose:()=>R(false)}):jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:Oe?"Session":"Waiting for participants..."}),!Oe&&jsx(Text,{dimColor:true,children:"No rounds started yet."}),jsx(zt,{participants:e.participants,onlineIds:t,hostId:e.settings.hostParticipantId,votes:{},revealed:false,participantId:o}),e.agenda.length>0&&jsx(Ds,{items:e.agenda,nextPending:Ze(e)}),i!==null&&_(i)!==null&&jsx(ks,{projection:e,round:i,rounds:r}),st.length>0&&jsxs(Box,{flexDirection:"column",children:[jsx(Text,{dimColor:true,children:"\u2500\u2500 History \u2500\u2500"}),st.map(x=>{let te=r.indexOf(x)+1;return jsx(Text,{dimColor:true,children:gr(x,te,r)},x.id)})]}),Z==="picking"&&Ae.length>0&&jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{children:"Hand off to:"}),Ae.map((x,te)=>jsxs(Text,{children:["[",te+1,"] ",x.displayName]},x.id)),jsx(Text,{dimColor:true,children:"[q] Cancel"})]}),Z==="picking"&&Ae.length===0&&jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{dimColor:true,children:"No other online participants"}),jsx(Text,{dimColor:true,children:"[q] Cancel"})]}),Z==="confirming"&&he&&jsx(Box,{flexDirection:"column",children:jsxs(Text,{children:["Hand off to ",e.participants.find(x=>x.id===he)?.displayName,"? [y/n]"]})}),b&&jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{gap:1,children:[jsx(Text,{children:"Round title (optional, Enter to skip):"}),jsx(F,{value:y,onChange:O,onSubmit:C,onCancel:M,placeholder:"Enter to skip",isActive:b})]}),jsx(Text,{dimColor:true,children:"[Esc] Cancel"})]}),A&&jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{gap:1,children:[jsx(Text,{children:"Ticket ID (optional, Enter to skip):"}),jsx(F,{value:P,onChange:ue,onSubmit:ie,onCancel:se,placeholder:"e.g. PROJ-1234",isActive:A})]}),jsx(Text,{dimColor:true,children:"[Esc] Cancel"})]}),Y&&jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{gap:1,children:[jsx(Text,{children:"Edit round title:"}),jsx(F,{value:X,onChange:Q,onSubmit:ve,onCancel:ge,placeholder:"Enter to save",isActive:Y})]}),jsx(Text,{dimColor:true,children:"[Esc] Cancel \xB7 empty submit cancels"})]}),fe&&jsxs(Box,{children:[jsx(Text,{color:"red",children:"End session for everyone? This cannot be undone. "}),jsx(Text,{dimColor:true,children:"y/n [Esc] Cancel"})]}),pe&&jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{gap:1,children:[jsx(Text,{children:"Agenda title (optional, Enter to skip):"}),jsx(F,{value:rt,onChange:an,onSubmit:We,onCancel:vt,placeholder:"Enter to skip",isActive:pe})]}),jsx(Text,{dimColor:true,children:"[Esc] Cancel"})]}),Ce&&jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{gap:1,children:[jsx(Text,{children:"Agenda ticket ID (optional, Enter to skip):"}),jsx(F,{value:dn,onChange:Ke,onSubmit:Ge,onCancel:Pe,placeholder:"e.g. PROJ-1234",isActive:Ce})]}),jsx(Text,{dimColor:true,children:"[Esc] Cancel"})]}),Z==="idle"&&!b&&!A&&!Y&&!fe&&!pe&&!Ce&&jsxs(Box,{gap:2,children:[n?jsx(Fragment,{children:i!==null&&_(i)!==null?jsxs(Fragment,{children:[_(i)!=="skipped"&&jsx(Text,{color:"yellow",children:"[v] Revote"}),jsx(Text,{color:"yellow",children:"[n] Next"}),jsx(Text,{color:"yellow",children:"[t] Edit title"}),jsx(Text,{color:"yellow",children:"[h] Handoff"}),jsx(Text,{color:"yellow",children:"[e] Settings"}),jsx(Text,{color:"yellow",children:"[c] Share"}),w&&jsx(Text,{color:"yellow",children:"[x] Export"}),jsxs(Text,{color:"yellow",children:["[w] ",f==="viewer"?"Vote":"Observe"]}),jsx(Text,{color:"yellow",children:"[m] Menu"})]}):jsxs(Fragment,{children:[jsx(Text,{color:"yellow",children:"[s] Start round"}),jsx(Text,{color:"yellow",children:"[a] Agenda"}),jsx(Text,{color:"yellow",children:"[h] Handoff"}),jsx(Text,{color:"yellow",children:"[e] Settings"}),jsx(Text,{color:"yellow",children:"[c] Share"}),w&&jsx(Text,{color:"yellow",children:"[x] Export"}),jsxs(Text,{color:"yellow",children:["[w] ",f==="viewer"?"Vote":"Observe"]}),jsx(Text,{color:"yellow",children:"[m] Menu"})]})}):jsxs(Fragment,{children:[jsx(Text,{dimColor:true,children:"Waiting for host to start a round..."}),jsx(Text,{children:"[c] Share"}),w&&jsx(Text,{color:"yellow",children:"[x] Export"}),jsxs(Text,{color:"yellow",children:["[w] ",f==="viewer"?"Vote":"Observe"]})]}),jsx(Text,{children:"[q] Quit"})]})]})}function ks({projection:e,round:t,rounds:n}){let o=n.indexOf(t)+1,r=fr(t,o,n);if(_(t)==="skipped")return jsx(Box,{flexDirection:"column",gap:1,children:jsx(Text,{bold:true,children:r})});let i=mr(t.votes),s=new Map(e.participants.map(p=>[p.id,p.displayName])),a=t.timerStartedAt!==void 0&&t.revealedAt!==void 0?Yn(t.timerStartedAt,t.revealedAt):null,d=Object.entries(t.votes),u=d.filter(([,p])=>!W(p)),c=d.filter(([,p])=>W(p)).map(([p])=>p),l=u[0]?.[1];return jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:r}),So(t)&&l!==void 0&&jsxs(Text,{bold:true,color:"green",children:["Consensus! Everyone voted ",l]}),jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{gap:2,children:[jsx(Text,{bold:true,underline:true,children:"Name".padEnd(20)}),jsx(Text,{bold:true,underline:true,children:"Estimate".padEnd(10)})]}),u.map(([p,I])=>jsxs(Box,{gap:2,children:[jsx(Text,{children:(s.get(p)??p).padEnd(20)}),jsx(Text,{color:"cyan",bold:true,children:I.padEnd(10)})]},p)),c.map(p=>jsxs(Box,{gap:2,children:[jsx(Text,{dimColor:true,children:(s.get(p)??p).padEnd(20)}),jsx(Text,{dimColor:true,children:"(abstained)".padEnd(10)})]},p)),e.participants.filter(p=>!(p.id in t.votes)).map(p=>jsxs(Box,{gap:2,children:[jsx(Text,{dimColor:true,children:p.displayName.padEnd(20)}),jsx(Text,{dimColor:true,children:"(no vote)".padEnd(10)})]},p.id))]}),jsxs(Box,{gap:2,children:[jsxs(Text,{children:["Avg: ",jsx(Text,{bold:true,children:i.average})]}),jsxs(Text,{children:["Med: ",jsx(Text,{bold:true,children:i.median})]}),jsxs(Text,{children:["Agreement: ",jsx(Text,{bold:true,children:i.agreement})]}),a!==null&&jsxs(Text,{dimColor:true,children:["\u23F1 ",a]})]})]})}var Ns={pending:"\u2022",consumed:"\u2713",skipped:"~",cancelled:"\u2717"},Ps={consumed:"green",skipped:"yellow",cancelled:"red"};function Ds({items:e,nextPending:t}){let n=e.filter(o=>o.state!=="cancelled");return jsxs(Box,{flexDirection:"column",children:[jsx(Text,{dimColor:true,children:"\u2500\u2500 Agenda \u2500\u2500"}),n.map(o=>{let r=Ns[o.state]??"?",i=Ps[o.state],s=t!==null&&o.id===t.id,a=[o.ticketId?`[${o.ticketId}]`:"",o.title??""].filter(Boolean).join(" ").trim()||o.id;return jsxs(Box,{gap:1,children:[i!==void 0?jsx(Text,{color:i,children:r}):jsx(Text,{children:r}),i!==void 0?jsx(Text,{color:i,children:a}):jsx(Text,{children:a}),s&&jsx(Text,{color:"cyan",children:"(next)"})]},o.id)}),n.length===0&&jsx(Text,{dimColor:true,children:"No pending items."})]})}function xr({scale:e,selected:t,onSelect:n,onClear:o,disabled:r}){let[i,s]=useState(0);return useInput((a,d)=>{if(!r)if(d.leftArrow)s(u=>Math.max(0,u-1));else if(d.rightArrow)s(u=>Math.min(e.cards.length-1,u+1));else if(d.return){let u=e.cards[i];u===t?o():n(u);}else (d.backspace||d.delete)&&o();}),jsxs(Box,{flexDirection:"column",gap:0,children:[jsx(Box,{gap:1,children:e.cards.map((a,d)=>{let u=d===i,c=a===t;return jsx(Text,{inverse:u,bold:c,...c&&{color:"cyan"},children:c?`[${a}]`:` ${a} `},a)})}),jsx(Text,{dimColor:true,children:" \u2190\u2192 navigate \u23CE select \u232B clear"})]})}function Bs(e){let t=Math.floor(e/1e3),n=Math.floor(t/60),o=t%60;return `${n}:${o.toString().padStart(2,"0")}`}function yr({projection:e,round:t,onlineIds:n,isHost:o,myId:r,myRole:i,elapsedMs:s,roomCode:a,shareOpen:d,settingsOpen:u,onVote:c,onClearVote:l,onReveal:p,onSkip:I,onDiscard:N,onToggleRole:R,onShare:T,onSetShareOpen:U,onOpenSettings:f,confirmingQuit:h}){let b=t.votes[r],y=b!==void 0&&W(b);if(useInput(P=>{if(P==="e"||P==="E"){f();return}if(P==="c"||P==="C"){U(true);return}if(i==="voter"&&(P==="a"||P==="A")){y?l():c(It);return}o&&(P==="r"||P==="R")&&p(),o&&(P==="s"||P==="S")&&I(),o&&(P==="d"||P==="D")&&N(),(P==="w"||P==="W")&&R();},{isActive:!h&&!u&&!d}),d)return jsx(Xt,{roomCode:a,onPick:P=>{U(false),T(P);},onClose:()=>U(false)});let O=b,C=e.rounds.indexOf(t)+1,M=t.title?` \u2014 ${t.title}`:"",A=t.ticketId?` [${t.ticketId}]`:"";return jsxs(Box,{flexDirection:"column",gap:1,children:[jsxs(Box,{gap:2,children:[jsxs(Text,{bold:true,children:["Round ",C,M,A]}),s!==void 0&&jsxs(Text,{dimColor:true,children:["\u23F1 ",Bs(s)]})]}),jsxs(Box,{gap:4,children:[jsx(zt,{participants:e.participants,onlineIds:n,hostId:e.settings.hostParticipantId,votes:t.votes,revealed:false}),i==="viewer"?jsx(Box,{flexDirection:"column",children:jsx(Text,{dimColor:true,children:"You're observing"})}):jsxs(Box,{flexDirection:"column",gap:1,children:[y&&jsx(Text,{dimColor:true,children:"(abstaining this round \u2014 press [a] to vote)"}),jsx(xr,{scale:t.scale,selected:y?void 0:O,onSelect:c,onClear:l,disabled:h||y})]})]}),jsxs(Box,{gap:2,children:[o&&jsx(Text,{color:"yellow",children:"[r] Reveal"}),o&&jsx(Text,{color:"yellow",children:"[s] Skip"}),o&&jsx(Text,{color:"yellow",children:"[d] Discard"}),i==="voter"&&jsxs(Text,{color:"yellow",children:["[a] ",y?"Vote":"Abstain"]}),jsxs(Text,{color:"yellow",children:["[w] ",i==="viewer"?"Vote":"Observe"]}),jsx(Text,{children:"[e] Settings"}),jsx(Text,{children:"[c] Share"}),jsx(Text,{children:"[q] Quit"})]})]})}var _s=3e3;function tn(e=_s){let[t,n]=useState(null),o=useRef(null),r=useCallback(()=>{o.current!==null&&(clearTimeout(o.current),o.current=null);},[]),i=useCallback(a=>{r(),n(a),o.current=setTimeout(()=>{n(null),o.current=null;},e);},[r,e]),s=useCallback(()=>{r(),n(null);},[r]);return useEffect(()=>()=>{r();},[r]),{notice:t,show:i,dismiss:s}}function Ys(e){let t=q(e);return !t||_(t)!==null?"lobby":"voting"}function on({session:e,participantId:t,displayName:n,accessMode:o,presetOverrides:r,customScales:i}){let{exit:s}=useApp(),[a,d]=useState(e.projection()),[u,c]=useState("connecting"),[l,p]=useState(e.onlineIds()),[I,N]=useState(),[R,T]=useState(false),[U,f]=useState(o==="password"?"password":"open"),[h,b]=useState(n),[y,O]=useState(false),[C,M]=useState(false),[A,P]=useState(""),[ue,ie]=useState(false),[se,Y]=useState(""),[X,Q]=useState(),[ve,ge]=useState(false),[m,w]=useState(""),[E,J]=useState(null),[pe,rt]=useState(false),[an,We]=useState(""),[vt,Ce]=useState(false),[dn,Ke]=useState(""),[Ge,Pe]=useState(),[Z,ee]=useState(),he=tn(3e3),[be,it]=useState(false),ae=tn(3e3),fe=tn(3e3);useEffect(()=>{let v=e.onChange(()=>{d(e.projection()),p(e.onlineIds());}),B=e.onStatusChange(c),qe=e.onHostChange(bt=>{let ci=e.projection().participants.find(ui=>ui.id===bt),li=bt===t?"You are now the host":`${ci?.displayName||"Unknown"} is now the host`;he.show(li);}),ln=setInterval(()=>{p(e.onlineIds());let bt=e.projection(),At=q(bt);At?.timerStartedAt!==void 0&&_(At)===null?N(Date.now()-At.timerStartedAt):N(void 0);},1e3);return ()=>{v(),B(),qe(),clearInterval(ln);}},[e,t,he.show]),useInput(v=>{(v==="q"||v==="Q")&&O(true);},{isActive:!R&&!y&&!C&&!ue&&!ve&&!be&&!pe&&!vt}),useInput((v,B)=>{v==="y"||v==="Y"?(e.disconnect(),s()):(v==="n"||v==="N"||B.escape)&&O(false);},{isActive:y});let De=Ys(a),Ae=q(a),Oe=a.settings.hostParticipantId===t,Ct=a.participants.find(v=>v.id===t),st=Ie(Ct??{}),x=useCallback(()=>{let v=Yt(Ze(a));P(v.title),ee(v.agendaItemId),M(true);},[a]),te=useCallback(v=>{M(false),P(""),Q(Mn(v));let B=Yt(Ze(a));Y(B.ticketId),ie(true);},[a]),$r=useCallback(()=>{M(false),P(""),Q(void 0),ee(void 0);},[]),Ur=useCallback(v=>{ie(false),Y("");let[B,qe,ln]=Xo(X,v,Z);e.newRound(B,qe,ln),Q(void 0),ee(void 0);},[e,X,Z]),Br=useCallback(()=>{ie(false),Y(""),Q(void 0),ee(void 0);},[]),Hr=useCallback(()=>{let v=e.current();!v||v.revealedAt===void 0||(J(v.id),w(v.title??""),ge(true));},[e]),Lr=useCallback(v=>{let B=E;if(ge(false),J(null),!B)return;let qe=v.trim();qe!==""&&e.updateRoundDescriptor(B,{title:qe});},[e,E]),jr=useCallback(()=>{ge(false),J(null);},[]),_r=useCallback(v=>{e.vote(v);},[e]),Fr=useCallback(()=>{e.unvote();},[e]),Vr=useCallback(()=>{e.reveal();},[e]),Yr=useCallback(()=>{e.skip();},[e]),Jr=useCallback(()=>{e.discardCurrentRound();},[e]),Wr=useCallback(()=>{let v=Yt(Ze(a));P(v.title),ee(v.agendaItemId),M(true);},[a]),Kr=useCallback(()=>{e.revote();},[e]),qn=useCallback(()=>{e.toggleRole();},[e]),Gr=useCallback(v=>{e.updateName(v);},[e]),qr=useCallback(v=>{e.updateScale(v);},[e]),zr=useCallback(v=>{e.updateDisplayName(v),b(v);},[e]),Xr=useCallback(async(v,B)=>{await e.updateAccess(v,B),f(v);},[e]),Qr=useCallback(v=>{try{e.handoffHost(v);}catch(B){console.error(`Handoff failed: ${B instanceof Error?B.message:String(B)}`);}},[e]),zn=useCallback(()=>{T(true);},[]),Zr=useCallback(()=>{T(false);},[]),ei=useCallback(()=>{e.endSessionForEveryone();},[e]),Xn=useCallback(async v=>{let B=v==="code"?_t(e.roomCode):v==="url"?Ft(e.roomCode):Vt(e.roomCode);try{await Cr.write(B),ae.show("Copied!");}catch{ae.show(`Copy failed \u2014 ${B}`);}},[e.roomCode,ae]),cn=a.rounds.filter(v=>_(v)!==null),ti=cn.length>0?cn.at(-1):null,ni=cn.length>0,oi=useCallback(()=>ur(a,v=>Cr.write(v),fe.show),[a,fe.show]),ri=useCallback(()=>{We(""),rt(true);},[]),ii=useCallback(v=>{rt(false),We("");let B=v.trim()===""?void 0:v.trim();Pe(B),Ke(""),Ce(true);},[]),si=useCallback(()=>{rt(false),We(""),Pe(void 0);},[]),ai=useCallback(v=>{Ce(false),Ke("");let B=v.trim()===""?void 0:v.trim();if(!Ge&&!B){Pe(void 0);return}Mt(e.doc,{...Ge!==void 0&&{title:Ge},...B!==void 0&&{ticketId:B},createdAt:Date.now()}),Pe(void 0);},[e.doc,Ge]),di=useCallback(()=>{Ce(false),Ke(""),Pe(void 0);},[]);return jsxs(Box,{flexDirection:"column",children:[jsx(er,{roomCode:e.roomCode,sessionName:a.settings.name,status:u,isHost:Oe}),he.notice&&jsx(Box,{paddingX:1,children:jsx(Text,{color:"yellow",children:he.notice})}),ae.notice&&jsx(Box,{paddingX:1,children:jsx(Text,{color:ae.notice.startsWith("Copy failed")?"red":"green",children:ae.notice})}),fe.notice&&jsx(Box,{paddingX:1,children:jsx(Text,{color:fe.notice.startsWith("Clipboard write failed")?"red":"green",children:fe.notice})}),R?jsx(dr,{sessionName:a.settings.name,displayName:h,currentScale:a.settings.defaultScale,accessMode:U,presetOverrides:r,customScales:i,isHost:Oe,onChangeName:Gr,onChangeScale:qr,onChangeDisplayName:zr,onChangeAccess:Xr,onClose:Zr}):De==="lobby"?jsx(hr,{projection:a,onlineIds:l,isHost:Oe,participantId:t,rounds:a.rounds,currentRound:ti,settingsOpen:R,onStartRound:x,onNewRound:Wr,roundTitlePromptActive:C,roundTitleInput:A,onRoundTitleChange:P,onRoundTitleSubmit:te,onRoundTitleCancel:$r,roundTicketIdPromptActive:ue,roundTicketIdInput:se,onRoundTicketIdChange:Y,onRoundTicketIdSubmit:Ur,onRoundTicketIdCancel:Br,onRevote:Kr,onOpenSettings:zn,onHandoffHost:Qr,onEndSession:ei,onShare:Xn,shareOpen:be,onSetShareOpen:it,roomCode:e.roomCode,confirmingQuit:y,myRole:st,onToggleRole:qn,descriptorPromptActive:ve,descriptorInput:m,onDescriptorChange:w,onDescriptorSubmit:Lr,onDescriptorCancel:jr,onEditDescriptor:Hr,canExport:ni,onExportResults:oi,onAgendaAdd:ri,agendaAddPromptActive:pe,agendaAddTitleInput:an,onAgendaAddTitleChange:We,onAgendaAddTitleSubmit:ii,onAgendaAddTitleCancel:si,agendaAddTicketIdPromptActive:vt,agendaAddTicketIdInput:dn,onAgendaAddTicketIdChange:Ke,onAgendaAddTicketIdSubmit:ai,onAgendaAddTicketIdCancel:di}):De==="voting"&&Ae?jsx(yr,{projection:a,round:Ae,onlineIds:l,isHost:Oe,myId:t,myRole:st,elapsedMs:I,onVote:_r,onClearVote:Fr,onReveal:Vr,onSkip:Yr,onDiscard:Jr,onToggleRole:qn,onShare:Xn,onSetShareOpen:it,shareOpen:be,settingsOpen:R,onOpenSettings:zn,roomCode:e.roomCode,confirmingQuit:y}):null,y&&jsx(Box,{children:jsx(Text,{dimColor:true,children:"Leave session? y/n"})})]})}function br({presetOverrides:e,customScales:t}){let{exit:n}=useApp(),[o,r]=useState("main-menu"),[i,s]=useState(Le()),[a,d]=useState(i.displayName??""),[u,c]=useState(i.relayUrl??""),[l,p]=useState(i.defaultSessionName??""),[I,N]=useState(i.avatarColor?.startsWith("#")?i.avatarColor:""),[R,T]=useState(t??[]),[U,f]=useState(e??{});useInput(m=>{(m==="q"||m==="Q")&&n();},{isActive:o==="main-menu"});let h=useMemo(()=>Ut(U,R),[U,R]),b=i.defaultScale,y=b?h.find(m=>m.id===b):void 0,O=[{label:"Display name",value:"display-name",detail:`[${i.displayName??"(none)"}]`},{label:"Relay URL",value:"relay-url",detail:`[${i.relayUrl??"(none)"}]`},{label:"Default scale",value:"default-scale",detail:`[${y?He(y.id,R):"(none)"}]`},{label:"Default session name",value:"default-session-name",detail:`[${i.defaultSessionName??"(none)"}]`},{label:"Default password",value:"default-password",detail:`[${i.defaultPassword?"on":"off"}]`},{label:"Avatar color",value:"avatar-color",detail:`[${zs(i.avatarColor)}]`}];function C(m){m==="display-name"?(d(i.displayName??""),r("editing-display-name")):m==="relay-url"?(c(i.relayUrl??""),r("editing-relay-url")):m==="default-scale"?r("picking-scale"):m==="default-session-name"?(p(i.defaultSessionName??""),r("editing-session-name")):m==="default-password"?r("picking-default-password"):m==="avatar-color"&&r("picking-avatar-color");}function M(m){if(m==="custom-hex"){N(i.avatarColor?.startsWith("#")?i.avatarColor:""),r("editing-avatar-hex");return}if(Me(m)===null){r("main-menu");return}s({...i,avatarColor:m}),V({avatarColor:m}),r("main-menu");}function A(m){let w=m.trim();if(w.length===0){r("picking-avatar-color");return}let E=w.startsWith("#")?w.toLowerCase():`#${w.toLowerCase()}`;Me(E)!==null&&(s({...i,avatarColor:E}),V({avatarColor:E}),r("main-menu"));}function P(m){let w=m.trim();if(w.length>0){let E={...i,displayName:w};s(E),V({displayName:w});}r("main-menu");}function ue(m){let w=m.trim();if(w.length>0){let E={...i,relayUrl:w};s(E),V({relayUrl:w});}r("main-menu");}function ie(m){let w=m.trim(),E=w.length>0?{...i,defaultSessionName:w}:{...i};w.length===0?(delete E.defaultSessionName,s(E),ut({defaultSessionName:""})):(s(E),V({defaultSessionName:w})),r("main-menu");}function se(m){let w=m.length>0?{...i,defaultScale:m}:{...i};m.length===0?(delete w.defaultScale,s(w),ut({defaultScale:""})):(s(w),V({defaultScale:m})),r("main-menu");}function Y(m,w){let E={...U};w.length===0?delete E[m]:E[m]=w,f(E),V({presetOverrides:Object.keys(E).length>0?E:void 0});}function X(m){let w=m==="on",E={...i,defaultPassword:w};s(E),V({defaultPassword:w}),r("main-menu");}function Q(m,w){let E=`custom-${randomUUID()}`,J=[...R,{id:E,label:m,cards:w}];T(J),s({...i,customScales:J}),V({customScales:J});}function ve(m,w,E){let J=R.map(pe=>pe.id===m?{id:m,label:w,cards:E}:pe);T(J),s({...i,customScales:J}),V({customScales:J});}function ge(m){let w=R.filter(J=>J.id!==m);T(w);let E={...i,customScales:w};i.defaultScale===m?(E.defaultScale="fibonacci",V({customScales:w,defaultScale:"fibonacci"})):V({customScales:w}),s(E);}if(o==="main-menu")return jsx(me,{title:"\u2500\u2500 Config Settings \u2500\u2500",items:O,onSelect:C,onClose:()=>n()});if(o==="editing-display-name")return jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Config Settings \u2500\u2500"}),jsx(Text,{children:"Display name: "}),jsx(F,{value:a,onChange:d,onSubmit:P,onCancel:()=>r("main-menu"),placeholder:"(required)",isActive:true}),jsx(Text,{dimColor:true,children:"\u23CE confirm esc back"})]});if(o==="editing-relay-url")return jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Config Settings \u2500\u2500"}),jsx(Text,{children:"Relay URL: "}),jsx(F,{value:u,onChange:c,onSubmit:ue,onCancel:()=>r("main-menu"),placeholder:"(required)",isActive:true}),jsx(Text,{dimColor:true,children:"\u23CE confirm esc back"})]});if(o==="editing-session-name")return jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Config Settings \u2500\u2500"}),jsx(Text,{children:"Default session name: "}),jsx(F,{value:l,onChange:p,onSubmit:ie,onCancel:()=>r("main-menu"),placeholder:"(leave empty to clear)",isActive:true}),jsx(Text,{dimColor:true,children:"\u23CE confirm esc back"})]});if(o==="picking-scale"){let m=[{id:"",cards:[]},...h];return jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Config Settings \u2500\u2500"}),jsx(Kt,{scales:m,selectedScaleId:b??"",presetOverrides:U,customScales:R,onSelect:se,onOverrideChange:Y,onCustomScaleCreate:Q,onCustomScaleEdit:ve,onCustomScaleDelete:ge,onClose:()=>r("main-menu"),showNoneOption:true})]})}if(o==="picking-avatar-color"){let m=at.map(w=>({label:ze[w].label,value:w,detail:i.avatarColor===w?"[current]":ze[w].base}));return m.push({label:"Custom hex\u2026",value:"custom-hex",detail:i.avatarColor?.startsWith("#")?`[${i.avatarColor}]`:void 0}),jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Config Settings \u2500\u2500"}),jsx(me,{title:"Avatar color:",items:m,onSelect:M,onClose:()=>r("main-menu")})]})}if(o==="editing-avatar-hex")return jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Config Settings \u2500\u2500"}),jsx(Text,{children:"Custom hex color: "}),jsx(F,{value:I,onChange:N,onSubmit:A,onCancel:()=>r("picking-avatar-color"),placeholder:"#rrggbb",isActive:true}),jsx(Text,{dimColor:true,children:"\u23CE confirm esc back"})]});if(o==="picking-default-password"){let m=[{label:"On",value:"on",detail:i.defaultPassword?"[current]":void 0},{label:"Off",value:"off",detail:i.defaultPassword?void 0:"[current]"}];return jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Config Settings \u2500\u2500"}),jsx(me,{title:"Default password:",items:m,onSelect:X,onClose:()=>r("main-menu")})]})}return jsx(Box,{})}function zs(e){return e?e.startsWith("#")?e:at.includes(e)?ze[e].label:e:"(auto)"}var Qs={pending:"\u2022",consumed:"\u2713",skipped:"~",cancelled:"\u2717"};function Zs(e){let t=Qs[e.state]??"?",n=[];e.ticketId&&n.push(`[${e.ticketId}]`),e.title&&n.push(e.title);let o=n.join(" ")||e.id;return `${t} ${o}`}async function xt(e){let t=new $e.Doc,n=new Awareness(t);Xe(t,{participantId:e.participantId,displayName:e.displayName}),n.setLocalStateField("participantId",e.participantId);let o=et({doc:t,awareness:n,roomCode:e.roomCode,roomUuid:e.roomUuid,participantId:e.participantId,relayUrl:e.relayUrl,...e.passwordHash!==void 0&&{passwordHash:e.passwordHash}});return await new Promise(r=>{let i=setTimeout(r,2e3),s=o.onStatusChange(a=>{a==="connected"&&setTimeout(()=>{clearTimeout(i),s(),r();},200);});}),{doc:t,disconnect:()=>o.disconnect()}}async function yt(){let e=Ht();e.length===0&&(console.error("No active session. Join a room first with: hnch join <code>"),process.exit(1));let t=e[0];return {roomCode:t.roomCode,roomUuid:t.roomUuid,...t.passwordHash!==void 0&&{passwordHash:t.passwordHash}}}async function Ir(e){!e.title?.trim()&&!e.ticket?.trim()&&(console.error("At least one of --title or --ticket is required"),process.exit(1));let t=await ce(),n=await yt();try{await le(t.relayUrl,n.roomCode);}catch{console.error(`Room ${n.roomCode} not found on relay \u2014 session may have expired.`),process.exit(1);}let{doc:o,disconnect:r}=await xt({relayUrl:t.relayUrl,participantId:t.participantId,displayName:t.displayName,roomCode:n.roomCode,roomUuid:n.roomUuid,...n.passwordHash!==void 0&&{passwordHash:n.passwordHash}});try{let i=Mt(o,{...e.title?.trim()?{title:e.title.trim()}:{},...e.ticket?.trim()?{ticketId:e.ticket.trim()}:{},...e.description?.trim()?{description:e.description.trim()}:{},createdAt:Date.now()});await new Promise(s=>{setTimeout(s,300);}),console.log(`Added agenda item: ${i}`);}finally{r();}}async function Rr(){let e=await ce(),t=await yt();try{await le(e.relayUrl,t.roomCode);}catch{console.error(`Room ${t.roomCode} not found on relay \u2014 session may have expired.`),process.exit(1);}let{doc:n,disconnect:o}=await xt({relayUrl:e.relayUrl,participantId:e.participantId,displayName:e.displayName,roomCode:t.roomCode,roomUuid:t.roomUuid,...t.passwordHash!==void 0&&{passwordHash:t.passwordHash}});try{let i=j(n).agenda;if(i.length===0){console.log("No agenda items.");return}i.forEach((s,a)=>{console.log(`${String(a+1).padStart(2)}. ${Zs(s)}`);});}finally{o();}}async function Tr(e){let t=await ce(),n=await yt();try{await le(t.relayUrl,n.roomCode);}catch{console.error(`Room ${n.roomCode} not found on relay \u2014 session may have expired.`),process.exit(1);}let{doc:o,disconnect:r}=await xt({relayUrl:t.relayUrl,participantId:t.participantId,displayName:t.displayName,roomCode:n.roomCode,roomUuid:n.roomUuid,...n.passwordHash!==void 0&&{passwordHash:n.passwordHash}});try{wn(o,e.id,"skipped",{timestamp:Date.now()}),await new Promise(i=>{setTimeout(i,300);}),console.log(`Skipped agenda item: ${e.id}`);}catch(i){console.error(`Skip failed: ${i instanceof Error?i.message:String(i)}`),process.exit(1);}finally{r();}}async function Er(e){let t=await ce(),n=await yt();try{await le(t.relayUrl,n.roomCode);}catch{console.error(`Room ${n.roomCode} not found on relay \u2014 session may have expired.`),process.exit(1);}let{doc:o,disconnect:r}=await xt({relayUrl:t.relayUrl,participantId:t.participantId,displayName:t.displayName,roomCode:n.roomCode,roomUuid:n.roomUuid,...n.passwordHash!==void 0&&{passwordHash:n.passwordHash}});try{wn(o,e.id,"cancelled",{timestamp:Date.now()}),await new Promise(i=>{setTimeout(i,300);}),console.log(`Cancelled agenda item: ${e.id}`);}catch(i){console.error(`Cancel failed: ${i instanceof Error?i.message:String(i)}`),process.exit(1);}finally{r();}}async function kr(e){let t=await ce(),n=await yt();try{await le(t.relayUrl,n.roomCode);}catch{console.error(`Room ${n.roomCode} not found on relay \u2014 session may have expired.`),process.exit(1);}let{doc:o,disconnect:r}=await xt({relayUrl:t.relayUrl,participantId:t.participantId,displayName:t.displayName,roomCode:n.roomCode,roomUuid:n.roomUuid,...n.passwordHash!==void 0&&{passwordHash:n.passwordHash}});try{wo(o,e.id,e.before,e.after),await new Promise(i=>{setTimeout(i,300);}),console.log(`Reordered agenda item: ${e.id}`);}catch(i){console.error(`Move failed: ${i instanceof Error?i.message:String(i)}`),process.exit(1);}finally{r();}}async function Gn(){return new Promise(e=>{let t=createInterface({input:process.stdin,output:process.stderr});process.stderr.write("Password: "),t.question("",n=>{t.close(),e(n);});})}async function na(e){let t=await ce(),n=e.scale??t.defaultScale??"fibonacci",o=e.name??t.defaultSessionName,r=e.password??t.defaultPassword??false,i;r&&(i=await Gn());let s=$t(n,t.presetOverrides,t.customScales);if(!s){let l=Object.keys(de).join(", ");console.error(`Unknown or fully-disabled scale: "${n}". Builtin IDs: ${l}`),process.exit(1);}let a=await Jo({participantId:t.participantId,displayName:t.displayName,relayUrl:t.relayUrl,sessionName:o,password:i,defaultScale:s,...t.avatarColor!==void 0&&{avatarColor:t.avatarColor}}),d;i&&(d=await Be(i,a.roomUuid)),On({roomCode:a.roomCode,roomUuid:a.roomUuid,lastSeenAt:Date.now(),...d!==void 0&&{passwordHash:d}}),console.error(`Room created: ${a.roomCode}`),console.error(`Share: hnch join ${a.roomCode}`),console.error("");let{waitUntilExit:u,unmount:c}=render(Qt.createElement(on,{session:a,participantId:t.participantId,displayName:t.displayName,accessMode:i?"password":"open",presetOverrides:t.presetOverrides,customScales:t.customScales}));jt({doc:a.doc,localParticipantId:t.participantId,onEnded:async l=>{console.error(l.isLocal?"Session ended.":`Session ended by ${l.hostName}.`),c();try{await Se();}catch(p){console.error(`Failed to clear cached session: ${p instanceof Error?p.message:String(p)}`);}a.disconnect(),process.exit(0);}}),await u(),a.disconnect(),Se(),process.exit(0);}async function oa(e){let t=await ce(),n=Ko(e.code);n===null&&(console.error("invalid room code"),process.exit(1));let o;e.password&&(o=await Gn());let r=await le(t.relayUrl,n),i;r.accessMode==="password"&&!e.password?i=await Gn():e.password&&(i=o);let s,a=false,d=await Wo({participantId:t.participantId,displayName:t.displayName,relayUrl:t.relayUrl,roomCode:n,password:i,...t.avatarColor!==void 0&&{avatarColor:t.avatarColor},onRejection(l){if(l==="unknown-room"){Lt({clearLastSession:Se,logger:console,exit:process.exit});return}l==="room-full"&&(a=true,s?.());}}),u;i&&(u=await Be(i,d.roomUuid)),On({roomCode:d.roomCode,roomUuid:d.roomUuid,lastSeenAt:Date.now(),...u!==void 0&&{passwordHash:u}}),console.error(`Joined room: ${d.roomCode}`),console.error("");let c=render(Qt.createElement(on,{session:d,participantId:t.participantId,displayName:t.displayName,accessMode:r.accessMode,presetOverrides:t.presetOverrides,customScales:t.customScales}));s=c.unmount,jt({doc:d.doc,localParticipantId:t.participantId,onEnded:async l=>{console.error(l.isLocal?"Session ended.":`Session ended by ${l.hostName}.`),s?.();try{await Se();}catch(p){console.error(`Failed to clear cached session: ${p instanceof Error?p.message:String(p)}`);}d.disconnect(),process.exit(0);}}),await c.waitUntilExit(),a&&(console.error("This room is full (max 20 participants)."),d.disconnect(),Se(),process.exit(1)),d.disconnect(),Se(),process.exit(0);}function ra(e,t=Date.now()){let n=t-e,o=Math.floor(n/6e4);return o<60?`${o}m ago`:`${Math.floor(o/60)}h ago`}async function ia(e){return new Promise((t,n)=>{let o=createInterface({input:process.stdin,output:process.stderr}),r=()=>{process.stderr.write(`Select [1-${e}]: `),o.question("",i=>{let s=parseInt(i.trim(),10);Number.isInteger(s)&&s>=1&&s<=e?(o.close(),t(s)):(process.stderr.write(`Invalid choice \u2014 enter a number between 1 and ${e}.
|
|
22
|
-
`),r());});};o.on("close",()=>n(new Error("stdin closed"))),r();})}async function
|
|
23
|
-
`);for(let[r,i]of t.entries()){let s=
|
|
18
|
+
`}function Lt(e,t,n){if(e.startsWith("custom-")){let r=(n??[]).find(i=>i.id===e);return r?{id:r.id,cards:r.cards}:void 0}let o=ae[e];if(o){let r=(t??{})[e]??[];if(r.length===0)return o;let i=o.cards.filter((s,a)=>!r.includes(a));return i.length===0?void 0:{id:e,cards:i}}}function _t(e,t){let n=Object.keys(ae).map(r=>Lt(r,e,t)).filter(r=>r!==void 0),o=(t??[]).map(r=>({id:r.id,cards:r.cards}));return [...n,...o]}function je(e,t){if(e.startsWith("custom-")){let n=(t??[]).find(o=>o.id===e);if(n&&n.label.trim().length>0)return n.label}return ho(e)}var os="https://hnch.dev";function ft(){let t=process.env.XDG_CONFIG_HOME||join(homedir(),".config");return join(t,"hnch")}function Un(){return join(ft(),"config.json")}function zo(){let e=ft();existsSync(e)||mkdirSync(e,{recursive:true});}function Fe(){let e=Un();if(!existsSync(e))return {};try{return JSON.parse(readFileSync(e,"utf-8"))}catch{return {}}}function F(e){zo();let n={...Fe(),...e};writeFileSync(Un(),JSON.stringify(n,null,2)+`
|
|
19
|
+
`,"utf-8");}async function rs(e){let t=createInterface({input:process.stdin,output:process.stderr});return new Promise(n=>{t.question(e,o=>{t.close(),n(o.trim());});})}function is(e){return e.startsWith("wss://")?"https://"+e.slice(6):e.startsWith("ws://")?"http://"+e.slice(5):e}async function ce(){let e=Fe(),t=false;if(e.participantId||(e.participantId=randomUUID(),t=true),!e.displayName){let o=await rs("Enter your display name: ");e.displayName=o||`user-${e.participantId.slice(0,6)}`,t=true;}e.relayUrl||(e.relayUrl=os,t=true),(!e.avatarColor||Me(e.avatarColor)===null)&&(e.avatarColor=xo(e.participantId),t=true),t&&F(e);let n=process.env.HNCH_RELAY_URL||e.relayUrl;return n=is(n),{participantId:e.participantId,displayName:e.displayName,relayUrl:n,defaultScale:e.defaultScale,defaultSessionName:e.defaultSessionName,defaultPassword:e.defaultPassword,presetOverrides:e.presetOverrides,customScales:e.customScales,avatarColor:e.avatarColor}}function mt(e){zo();let n={...Fe()};for(let[o,r]of Object.entries(e))r===""?delete n[o]:r!==void 0&&(n[o]=r);writeFileSync(Un(),JSON.stringify(n,null,2)+`
|
|
20
|
+
`,"utf-8");}async function Xo(e,t){let n=await fetch(`${e}/rooms`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({})});if(!n.ok)throw new Error(`POST /rooms failed: ${n.status}`);return await n.json()}async function le(e,t){let n=await fetch(`${e}/rooms/${encodeURIComponent(t)}`);if(n.status===404){let o=await n.json().catch(()=>null);throw new Error(`Room not found: ${o?.reason??"unknown-room"}`)}if(!n.ok)throw new Error(`GET /rooms/:code failed: ${n.status}`);return await n.json()}async function Bn(e,t,n){let o=await fetch(`${e}/rooms/${t}/access`,{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify({passwordHash:n})});if(!o.ok)throw new Error(`PATCH /rooms/:uuid/access failed: ${o.status}`)}function Qo(e){let n=`${e.wsBaseUrl.replace(/^http/,"ws")}/ws`,o={did:e.deviceId};e.passwordHash!==void 0&&(o.pw=e.passwordHash);let r=new WebsocketProvider(n,e.roomUuid,e.doc,{params:o,connect:true,...e.awareness!==void 0&&{awareness:e.awareness},WebSocketPolyfill:as}),i=u=>{e.onStatusChange?.(u.status);},s=u=>{if(u===null)return;let c=lo.get(u.code);c!==void 0&&(e.onRejection?.(c),r.shouldConnect=false,r.disconnect());};r.on("status",i),r.on("connection-close",s);let a=false,d=e.passwordHash;return {doc:e.doc,awareness:r.awareness,updateCredentials(u){if(u.passwordHash===d)return;d=u.passwordHash??void 0,r.shouldConnect=false,r.disconnect();let l={did:r.params.did??""};d!==void 0&&(l.pw=d),r.params=l,r.connect();},disconnect(){a||(a=true,r.off("status",i),r.off("connection-close",s),r.shouldConnect=false,r.disconnect(),r.destroy());}}}function Zo(e,t,n){let o=null,r=null;function i(){let u=new Set;return t.getStates().forEach(c=>{let l=c.participantId;typeof l=="string"&&u.add(l);}),u}function s(){r!==null&&(clearTimeout(r),r=null),o=null;}function a(){r=null;let u=o;o=null;let c=Po(_(e),i(),n,u);c.promote&&Be(e,{hostParticipantId:c.winner});}function d(){let u=No(_(e),i(),{missingHostId:o});switch(u.kind){case "cancel":s();break;case "start-debounce":s(),o=u.hostId,r=setTimeout(a,Eo);break;}}return t.on("change",d),e.getMap(lt).observe(d),d(),{stop(){s(),t.off("change",d),e.getMap(lt).unobserve(d);}}}async function nr(e){let t,n=await Xo(e.relayUrl);e.password&&(t=await _e(e.password,n.uuid),await Bn(e.relayUrl,n.uuid,t));let o=new $e.Doc,r=new Awareness(o),i=Date.now();return wn(o,{roomUuid:n.uuid,createdAt:i,participantId:e.participantId,displayName:e.displayName,defaultScale:e.defaultScale??kt,...e.sessionName!==void 0&&{sessionName:e.sessionName},...e.avatarColor!==void 0&&{avatarColor:e.avatarColor}}),r.setLocalStateField("participantId",e.participantId),et({doc:o,awareness:r,roomCode:n.code,roomUuid:n.uuid,participantId:e.participantId,relayUrl:e.relayUrl,passwordHash:t})}async function or(e){let t=await le(e.relayUrl,e.roomCode),n;if(t.accessMode==="password"){if(!e.password)throw new Error("Room requires a password");n=await _e(e.password,t.uuid);}let o=new $e.Doc,r=new Awareness(o);return Ue(o,{participantId:e.participantId,displayName:e.displayName,...e.avatarColor!==void 0&&{avatarColor:e.avatarColor}}),r.setLocalStateField("participantId",e.participantId),et({doc:o,awareness:r,roomCode:e.roomCode,roomUuid:t.uuid,participantId:e.participantId,relayUrl:e.relayUrl,passwordHash:n,onRejection:e.onRejection})}function et(e){let{doc:t,awareness:n,participantId:o,relayUrl:r,roomUuid:i}=e,s=new Set,a=new Set,d=new Set,u=Qo({wsBaseUrl:e.relayUrl,roomUuid:e.roomUuid,doc:t,deviceId:o,passwordHash:e.passwordHash,awareness:n,onStatusChange(f){s.forEach(h=>h(f));},onRejection(f){console.error(`Connection rejected: ${f}`),e.onRejection?.(f);}}),c=Zo(t,n,o),l=()=>{a.forEach(f=>f());};t.getMap("meta").observeDeep(l),t.getMap("settings").observeDeep(l),t.getMap("participants").observeDeep(l),t.getArray("rounds").observeDeep(l);function p(){let f=new Set;return n.getStates().forEach(h=>{let b=h.participantId;typeof b=="string"&&f.add(b);}),f}let A=new Set,N=setInterval(()=>{let f=_(t),h=W(f);!h||A.has(h.id)||So(h,f.participants,p())&&(A.add(h.id),Pn(t));},250),R=t.getMap("settings").get("hostParticipantId"),T=()=>{let f=t.getMap("settings").get("hostParticipantId");f!==R&&f!==void 0&&d.forEach(h=>h(f)),R=f;};t.getMap("settings").observe(T);let U=false;return {doc:t,awareness:n,roomCode:e.roomCode,roomUuid:e.roomUuid,projection(){return _(t)},current(){return W(_(t))},isHost(){return _(t).settings.hostParticipantId===o},onlineIds:p,vote(f){let h=W(_(t));h&&Cn(t,h.id,o,f);},unvote(){let f=W(_(t));f&&bn(t,f.id,o);},reveal(){Pn(t);},skip(){jo(t);},newRound(f,h,b){let y=randomUUID(),O=Date.now();return Ut(t,{id:y,createdAt:O,createdBy:o,...f!==void 0&&{title:f},...h!==void 0&&{ticketId:h},...b!==void 0&&{agendaItemId:b}}),y},discardCurrentRound(){Fo(t,o);},revote(){let f=W(_(t)),h=randomUUID();return Ut(t,{id:h,createdAt:Date.now(),createdBy:o,...f?.id!==void 0&&{parentRoundId:f.id},...f?.title!==void 0&&{title:f.title},...f?.description!==void 0&&{description:f.description},...f?.ticketId!==void 0&&{ticketId:f.ticketId},...f?.agendaItemId!==void 0&&{agendaItemId:f.agendaItemId}}),h},updateRoundDescriptor(f,h){yn(t,f,h);},updateName(f){Be(t,{name:f});},updateScale(f){Be(t,{defaultScale:f});},updateDisplayName(f){let y=_(t).participants.find(O=>O.id===o)?.joinedAt??Date.now();$t(t,o,{displayName:f,joinedAt:y});},async updateAccess(f,h){let b=null;if(f==="password"){if(!h)throw new Error("Password required for password mode");b=await _e(h,i);}await Bn(r,i,b),u.updateCredentials({passwordHash:b});},handoffHost(f){if(!this.isHost())throw new Error("Only the current host can hand off");if(!p().has(f))throw new Error("Target participant is not online");if(!_(t).participants.some(O=>O.id===f))throw new Error("Target participant does not exist");Be(t,{hostParticipantId:f});},toggleRole(){let h=_(t).participants.find(C=>C.id===o),y=Ae(h??{})==="viewer"?"voter":"viewer",O=h?.joinedAt??Date.now();$t(t,o,{displayName:h?.displayName??"",joinedAt:O,role:y});},endSessionForEveryone(){if(!this.isHost())throw new Error("Only the current host can end the session");In(t);},onChange(f){return a.add(f),()=>a.delete(f)},onStatusChange(f){return s.add(f),()=>s.delete(f)},onHostChange(f){return d.add(f),()=>d.delete(f)},disconnect(){U||(U=true,clearInterval(N),c.stop(),t.getMap("meta").unobserveDeep(l),t.getMap("settings").unobserveDeep(l),t.getMap("settings").unobserve(T),t.getMap("participants").unobserveDeep(l),t.getArray("rounds").unobserveDeep(l),u.disconnect());}}}function rr(e){let t=kn(e);return t===""?null:t}function Ve(){return join(ft(),"last-session.json")}function ps(e,t){let n=ft();mkdirSync(n,{recursive:true,mode:448}),chmodSync(n,448),writeFileSync(e,t,{encoding:"utf-8",mode:384}),chmodSync(e,384);}function Ln(){let e=Ve();try{unlinkSync(e);}catch(t){if(t.code!=="ENOENT")throw t}}function _n(){let e=Ve();if(!existsSync(e))return {};try{let t=JSON.parse(readFileSync(e,"utf-8"));return {...En(t).entries}}catch{return {}}}function jn(e){let t={version:2,entries:e};ps(Ve(),JSON.stringify(t,null,2)+`
|
|
21
|
+
`);}function Ft(e){let t=Date.now();if(!existsSync(Ve()))return [];let n;try{n=JSON.parse(readFileSync(Ve(),"utf-8"));}catch{return []}let o=En(n),r=Mo(o,t),i=Object.values(r.entries);return i.length===0?(Ln(),[]):i.toSorted((s,a)=>a.lastSeenAt-s.lastSeenAt)}function fs(e,t){return e!==void 0?{passwordHash:e}:t!==void 0?{passwordHash:t}:{}}function Fn(e){let t=Date.now(),n=_n(),o=n[e.roomUuid];n[e.roomUuid]={roomCode:e.roomCode,roomUuid:e.roomUuid,lastSeenAt:e.lastSeenAt??t,...fs(e.passwordHash,o?.passwordHash)};let r=Object.keys(n);if(r.length>5){let i=r.toSorted((s,a)=>(n[s]?.lastSeenAt??0)-(n[a]?.lastSeenAt??0)).slice(0,r.length-5);for(let s of i)delete n[s];}jn(n);}function gt(e){if(!existsSync(Ve()))return;let t=_n();if(delete t[e],Object.keys(t).length===0){Ln();return}jn(t);}function ms(){Ln();}function Vn(e){if(!existsSync(Ve()))return;let t=_n(),n=t[e];if(!n)return;let{passwordHash:o,...r}=n;t[e]=r,jn(t);}function Yn(e){Fn(e);}function Se(){ms();}async function Vt(e){let t=true;try{await e.clearLastSession();}catch(n){t=false,e.logger.error(`Failed to clear cached session: ${n instanceof Error?n.message:String(n)}`);}return t?e.logger.error("Session expired (room no longer exists). Cached session cleared."):e.logger.error("Session expired. Could not delete ~/.config/hnch/last-session.json \u2014 please remove it manually."),e.exit(1)}function Yt(e){let t=e.doc.getMap("meta"),n=null,o=false;function r(){if(o)return;let i=t.get("sessionEndedAt");if(i==null||i===n)return;n=i;let s=t.get("createdBy"),a=s===e.localParticipantId,d=e.doc.getMap("participants"),u=e.doc.getMap("settings").get("hostParticipantId")??s,c="host";if(u){let p=d.get(u)?.get("displayName");typeof p=="string"&&p.length>0&&(c=p);}setImmediate(()=>{o||e.onEnded({isLocal:a,hostName:c,timestamp:i});});}return t.observe(r),r(),()=>{o=true,t.unobserve(r);}}var gs="@xauyxau/hnch";function Kt(e){return _o(e)}function Jt(e){return `${process.env.HNCH_SHARE_ORIGIN??"https://hnch.dev"}/join?code=${e}`}function Gt(e){return `npx ${gs} join ${e}`}function Kn(e){let t=e.trim();return t===""?void 0:t}function Wt(e){return e?{title:e.title??"",ticketId:e.ticketId??"",agendaItemId:e.id}:{title:"",ticketId:"",agendaItemId:void 0}}function dr(e,t,n){return [e,Kn(t),n]}var hs={connecting:"yellow",connected:"green",disconnected:"red"};function ur({roomCode:e,sessionName:t,status:n,isHost:o}){let r=t?`${e} \xB7 ${t}`:e;return jsxs(Box,{borderStyle:"single",borderColor:"gray",paddingX:1,justifyContent:"space-between",children:[jsxs(Text,{bold:true,children:["hnch \xB7 ",r]}),jsxs(Box,{gap:2,children:[o&&jsx(Text,{color:"yellow",children:"[host]"}),jsx(Text,{color:hs[n],children:n})]})]})}function me({items:e,onSelect:t,onClose:n,title:o}){if(e.length===0)return jsxs(Box,{flexDirection:"column",gap:1,children:[o&&jsx(Text,{bold:true,children:o}),jsx(Text,{dimColor:true,children:"(no items)"})]});let r=e.findIndex(a=>!a.disabled),[i,s]=useState(Math.max(r,0));return useInput((a,d)=>{if(d.upArrow)s(u=>{let c=(u-1+e.length)%e.length,l=0;for(;e[c]?.disabled&&l<e.length;)c=(c-1+e.length)%e.length,l++;return c});else if(d.downArrow)s(u=>{let c=(u+1)%e.length,l=0;for(;e[c]?.disabled&&l<e.length;)c=(c+1)%e.length,l++;return c});else if(d.return){let u=e[i];u&&!u.disabled&&t(u.value);}else d.escape&&n?.();}),jsxs(Box,{flexDirection:"column",gap:1,children:[o&&jsx(Text,{bold:true,children:o}),jsx(Box,{flexDirection:"column",children:e.map((a,d)=>{let u=d===i,c=a.disabled??false;return jsxs(Box,{gap:1,children:[jsx(Text,{...u&&{color:"cyan"},dimColor:c,children:u?">":" "}),jsx(Text,{bold:u,dimColor:c,children:a.label}),a.detail&&jsx(Text,{dimColor:true,children:a.detail})]},a.value)})}),jsx(Text,{dimColor:true,children:"\u2191\u2193 select \u23CE confirm esc close"})]})}function j({value:e,onChange:t,onSubmit:n,onCancel:o,placeholder:r,isActive:i=true,mask:s=false}){useInput((c,l)=>{l.escape?o?.():l.return?n(e):l.backspace||l.delete?t(e.slice(0,-1)):c&&!l.ctrl&&!l.meta&&t(e+c);},{isActive:i});let a=s&&e.length>0?"*".repeat(e.length):e,d=a.length>0?a:r??"",u=e.length===0&&r!==void 0;return jsxs(Text,{children:[jsx(Text,{dimColor:u,children:d}),jsx(Text,{inverse:true,children:" "})]})}function gr({mode:e,password:t,onModeChange:n,onPasswordChange:o,onClose:r}){let[i,s]=useState(e==="open"?0:1),[a,d]=useState(false);return useEffect(()=>{s(e==="open"?0:1);},[e]),useInput((u,c)=>{if(c.leftArrow)s(l=>Math.max(0,l-1));else if(c.rightArrow)s(l=>Math.min(1,l+1));else if(c.return){let l=i===0?"open":"password";l!==e&&n(l),l==="password"&&d(true);}else c.escape&&r?.();},{isActive:!a}),jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Box,{gap:1,children:["open","password"].map((u,c)=>{let l=c===i,p=u===e,A=u==="open"?"Open":"Password";return jsx(Text,{inverse:l,bold:p,...p&&{color:"cyan"},children:p?`[${A}]`:` ${A} `},u)})}),e==="password"&&jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{children:"Password: "}),jsx(j,{value:t,onChange:o,onSubmit:()=>d(false),onCancel:()=>d(false),placeholder:"(required to join)",isActive:a,mask:true}),!a&&jsx(Text,{dimColor:true,children:"\u23CE edit \u2190 \u2192 switch mode esc close"}),a&&jsx(Text,{dimColor:true,children:"\u23CE done esc cancel"})]}),e==="open"&&jsx(Text,{dimColor:true,children:"\u2190\u2192 toggle \u23CE confirm esc close"})]})}function xr({scaleId:e,cards:t,disabledIndices:n,onOverrideChange:o,onClose:r}){let i=useMemo(()=>new Set(n),[n]),[s,a]=useState(0),d=u=>{let c=new Set(i);if(c.has(u))c.delete(u);else {if(c.size>=t.length-1)return;c.add(u);}let l=Array.from(c).toSorted((p,A)=>p-A);o(e,l);};return useInput((u,c)=>{c.leftArrow?a(l=>Math.max(0,l-1)):c.rightArrow?a(l=>Math.min(t.length-1,l+1)):u===" "?d(s):(c.return||c.escape)&&r();}),jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Box,{gap:1,children:t.map((u,c)=>{let l=c===s,p=i.has(c);return jsx(Text,{inverse:l,bold:!p,...!p&&{color:"cyan"},strikethrough:p,dimColor:p,children:u},u)})}),jsx(Text,{dimColor:true,children:" \u2190\u2192 navigate space toggle \u23CE/esc done"})]})}function Zn({initialName:e="",initialCards:t=[],onSave:n,onCancel:o}){let r=e.length>0,[i,s]=useState(e),[a,d]=useState(t.length>0?t:[""]),[u,c]=useState(0),[l,p]=useState("editing-name"),[A,N]=useState(""),R=()=>{let f=i.trim();if(f.length===0||f.length>40){N("Name must be 1-40 characters");return}s(f),N(""),p("editing-cards");},T=()=>{let f=i.trim();if(f.length===0||f.length>40){N("Name must be 1-40 characters");return}let h=a.map(y=>y.trim()).filter(y=>y.length>0),b=Array.from(new Set(h));if(b.length<2){N("Need at least 2 unique non-empty cards");return}N(""),n(f,b);};return useInput((f,h)=>{if(l==="editing-cards"){if(h.leftArrow)c(b=>Math.max(0,b-1));else if(h.rightArrow)c(b=>{let y=b+1;return y>=a.length&&a.length<25?(d(O=>[...O,""]),y):Math.min(y,a.length-1)});else if(h.return)T();else if(h.escape)o();else if(h.tab)p("editing-name");else if(h.backspace){let b=a[u]||"";if(b.length===0){if(a.length>2){let y=a.filter((O,C)=>C!==u);d(y),c(Math.max(0,u-1));}}else {let y=[...a];y[u]=b.slice(0,-1),d(y);}}else if(f&&!h.ctrl&&!h.meta){let b=a[u]||"";if(b.length<10){let y=[...a];y[u]=b+f,d(y);}}}},{isActive:l==="editing-cards"}),jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:r?"\u2500\u2500 Edit Custom Scale \u2500\u2500":"\u2500\u2500 Create Custom Scale \u2500\u2500"}),jsxs(Box,{flexDirection:"column",gap:0,children:[jsx(Text,{children:"Name:"}),jsx(j,{value:i,onChange:s,onSubmit:R,onCancel:o,placeholder:"Scale name",isActive:l==="editing-name"})]}),l==="editing-cards"&&jsxs(Box,{flexDirection:"column",gap:0,children:[jsx(Text,{children:"Cards:"}),jsx(Box,{gap:1,flexWrap:"wrap",children:a.map((f,h)=>{let b=h===u;return jsx(Text,{inverse:b,...!b&&{color:"cyan"},children:f.length>0?f:"\xB7"},h)})})]}),A&&jsx(Text,{color:"red",children:A}),jsx(Text,{dimColor:true,children:l==="editing-name"?"\u23CE next esc cancel":"\u2190\u2192 navigate typing adds card bsp delete \u23CE save tab name esc cancel"})]})}function Xt({scales:e,selectedScaleId:t,presetOverrides:n,customScales:o=[],onSelect:r,onOverrideChange:i,onCustomScaleCreate:s,onCustomScaleEdit:a,onCustomScaleDelete:d,onClose:u,showNoneOption:c=false}){let[l,p]=useState(0),[A,N]=useState(null),[R,T]=useState("browsing"),[U,f]=useState(null),[h,b]=useState(null),y=s?[...e,{id:"__create-custom__",cards:[]}]:e,O=y.length;if(useInput((C,M)=>{if(R==="browsing"){if(M.escape){u();return}if(O===0)return;if(M.upArrow)p(I=>(I-1+O)%O);else if(M.downArrow)p(I=>(I+1)%O);else if(M.return){let I=y[l];if(!I)return;if(I.id==="__create-custom__"){T("creating");return}I.id in ae?N(A===I.id?null:I.id):r(I.id);}else if(C===" "){let I=y[l];I&&I.id!=="__create-custom__"&&r(I.id);}else if(C==="e"||C==="E"){let I=y[l];a&&I?.id.startsWith("custom-")&&(f(I.id),T("editing"));}else if(C==="d"||C==="D"){let I=y[l];d&&I?.id.startsWith("custom-")&&(b(I.id),T("confirming-delete"));}}else R==="confirming-delete"&&(C==="y"||C==="Y"?(h&&d&&d(h),b(null),T("browsing")):(C==="n"||C==="N"||M.escape)&&(b(null),T("browsing")));},{isActive:R==="browsing"&&A===null||R==="confirming-delete"}),R==="creating")return jsx(Zn,{onSave:(C,M)=>{s&&s(C,M),T("browsing");},onCancel:()=>T("browsing")});if(R==="editing"&&U){let C=o?.find(I=>I.id===U);if(e.find(I=>I.id===U)&&C)return jsx(Zn,{initialName:C.label,initialCards:C.cards,onSave:(I,P)=>{a&&a(U,I,P),f(null),T("browsing");},onCancel:()=>{f(null),T("browsing");}})}if(R==="confirming-delete"&&h){let C=y.find(I=>I.id===h),M=C?je(C.id,o):"Unknown";return jsxs(Box,{flexDirection:"column",gap:1,children:[jsxs(Text,{children:["Delete ",M,"? "]}),jsx(Text,{children:"[y] yes [n] no esc cancel"})]})}return y.length===0?jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{dimColor:true,children:"(no scales available)"}),jsx(Text,{dimColor:true,children:"esc back"})]}):jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Box,{flexDirection:"column",children:y.map((C,M)=>{let I=M===l,P=C.id===t,ue=A===C.id,re=C.id in ae,ie=C.id==="__create-custom__",V=C.cards.join(", "),z=c&&C.id==="",X=z?"(none)":ie?"[+ Create custom scale]":je(C.id,o);return jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{gap:1,children:[jsx(Text,{...I&&{color:"cyan"},children:I?">":" "}),jsx(Text,{bold:I,children:X}),!z&&!ie&&jsx(Text,{dimColor:true,children:V}),P&&jsx(Text,{color:"cyan",children:"[current]"})]}),ue&&!z&&!ie&&jsx(Box,{paddingLeft:2,children:re?jsx(xr,{scaleId:C.id,cards:ae[C.id]?.cards??[],disabledIndices:n?.[C.id]??[],onOverrideChange:i,onClose:()=>N(null)}):null})]},C.id||"none")})}),jsx(Text,{dimColor:true,children:(()=>{let C=l<y.length?y[l]:null;return C?.id.startsWith("custom-")?`\u2191\u2193 navigate space select${a?" [e] edit":""}${d?" [d] delete":""} esc back`:C&&C.id in ae?"\u2191\u2193 navigate \u23CE customize space select esc back":"\u2191\u2193 navigate \u23CE/space select esc back"})()})]})}function Ns(e,t){return t?[...e]:e.filter(n=>n.value==="display-name")}function wr({sessionName:e,displayName:t,currentScale:n,accessMode:o,presetOverrides:r,customScales:i,isHost:s=true,onChangeName:a,onChangeScale:d,onChangeDisplayName:u,onChangeAccess:c,onClose:l}){let[p,A]=useState(r??{}),N=useMemo(()=>_t(p,i),[p,i]),[R,T]=useState("main-menu"),[U,f]=useState(e??""),[h,b]=useState(t),[y,O]=useState(o==="password"?"password":"open"),[C,M]=useState(""),[I,P]=useState(false),ue=[{label:"Room name",value:"room-name",detail:`[${e??"(none)"}]`},{label:"Scale",value:"scale",detail:`[${je(n.id,i)}]`},{label:"Access",value:"access",detail:`[${o==="open"?"Open":"Password"}]`},{label:"Display name",value:"display-name",detail:`[${t}]`}],re=Ns(ue,s);function ie(m){!s&&m!=="display-name"||(m==="room-name"?(f(e??""),T("editing-room-name")):m==="scale"?T("picking-scale"):m==="access"?T("picking-access"):m==="display-name"&&(b(t),T("editing-display-name")));}function V(m){let x=m.trim()===""?void 0:m.trim();a(x),T("main-menu");}function z(m){let x=m.trim();x.length>0&&(u(x),process.nextTick(()=>F({displayName:x}))),T("main-menu");}function X(m){let x=N.find(E=>E.id===m);x&&d(x),T("main-menu");}function ve(m,x){let E={...p};x.length===0?delete E[m]:E[m]=x,A(E),F({presetOverrides:Object.keys(E).length>0?E:void 0});}async function ge(m,x){P(true);try{await c(m,x),O(m),M(m==="password"?x??"":"");}catch(E){console.error(`Failed to update access: ${E}`);}finally{P(false),T("main-menu");}}return R==="main-menu"?jsx(me,{title:"\u2500\u2500 Settings \u2500\u2500",items:re,onSelect:ie,onClose:l}):R==="editing-room-name"?jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Settings \u2500\u2500"}),jsx(Text,{children:"Room name: "}),jsx(j,{value:U,onChange:f,onSubmit:V,onCancel:()=>T("main-menu"),placeholder:"(leave empty to remove)",isActive:true}),jsx(Text,{dimColor:true,children:"\u23CE confirm esc back"})]}):R==="editing-display-name"?jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Settings \u2500\u2500"}),jsx(Text,{children:"Display name: "}),jsx(j,{value:h,onChange:b,onSubmit:z,onCancel:()=>T("main-menu"),placeholder:"(required)",isActive:true}),jsx(Text,{dimColor:true,children:"\u23CE confirm esc back"})]}):R==="picking-scale"?jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Settings \u2500\u2500"}),jsx(Xt,{scales:N,selectedScaleId:n.id,presetOverrides:p,onSelect:X,onOverrideChange:ve,onClose:()=>T("main-menu")})]}):R==="picking-access"?jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Settings \u2500\u2500"}),I&&jsx(Text,{dimColor:true,children:"Updating access..."}),!I&&jsx(gr,{mode:y,password:C,onModeChange:m=>{m==="open"&&ge("open");},onPasswordChange:M,onClose:()=>T("main-menu")})]}):jsx(Box,{})}function en({participants:e,onlineIds:t,hostId:n,votes:o,revealed:r,participantId:i}){return jsxs(Box,{flexDirection:"column",children:[jsxs(Text,{bold:true,children:["Participants (",e.length,")"]}),e.map(s=>{let a=t.has(s.id),d=a?"\u25CF":"\u25CB",u=a?"green":"gray",c=s.id===n,l=Ae(s)==="viewer",p=s.id===i,A=s.id in o,N=l?" (viewer)":r?o[s.id]?` \u2192 ${o[s.id]}`:"":A?" \u2713":" \xB7",R=p&&!l&&!(r&&o[s.id]);return jsxs(Box,{gap:1,children:[jsx(Text,{color:u,children:d}),jsxs(Text,{children:[s.displayName,c?" (host)":""]}),R?jsx(Text,{color:"cyan",children:"(voter)"}):jsx(Text,{color:l?"gray":A?"green":"gray",children:N})]},s.id)})]})}var Ps=[{label:"End session for everyone",value:"end-session",detail:"Disconnects all participants. Cannot be undone."}];function vr({onPick:e,onClose:t}){return jsx(me,{title:"Host Actions",items:Ps,onSelect:e,onClose:t})}function tn({roomCode:e,onPick:t,onClose:n}){let o=[{label:"Copy code",value:"code",detail:Kt(e)},{label:"Copy share link",value:"url",detail:Jt(e)},{label:"Copy npx command",value:"npx",detail:Gt(e)}];return jsx(me,{title:"Share",items:o,onSelect:r=>t(r),onClose:n})}function Ms(e){let t=e.rounds.filter(o=>de(o.status)),n=Object.fromEntries(e.participants.map(o=>[o.id,o]));return Go({rounds:t,participants:n})}async function Cr(e,t,n){let o=Ms(e);try{await t(o),n("Results copied to clipboard");}catch{n("Clipboard write failed");}}function br(e,t,n){let o=Uo(e.id,n);return o===null?`Round ${t}`:`Round ${o.depth}/${o.total} [re-vote]`}function Ir(e,t,n){let o=br(e,t,n),r=e.title?` \u2014 ${e.title}`:"",i=e.ticketId?` [${e.ticketId}]`:"",s=e.status==="skipped"?" \u2014 Skipped":" \u2014 Results";return `${o}${r}${i}${s}`}function Ar(e){let t=Object.values(e).filter(c=>!K(c)).map(c=>parseFloat(c)).filter(c=>!isNaN(c)).toSorted((c,l)=>c-l);if(t.length===0)return {average:"-",median:"-",agreement:"-"};let o=t.reduce((c,l)=>c+l,0)/t.length,r=Math.floor(t.length/2),i=t.length%2===0?(t[r-1]+t[r])/2:t[r],s=Object.values(e).filter(c=>!K(c)),a=new Map;for(let c of s)a.set(c,(a.get(c)??0)+1);let d=Math.max(...a.values()),u=s.length>0?Math.round(d/s.length*100):0;return {average:o.toFixed(1),median:i.toFixed(1),agreement:`${u}%`}}function to(e,t){let n=Math.floor((t-e)/1e3),o=Math.floor(n/60),r=n%60;return `${o}:${r.toString().padStart(2,"0")}`}function Rr(e,t,n=[]){let o=br(e,t,n);if(e.status==="skipped"){let l=e.title?` ${e.title}`:"",p=e.ticketId?` [${e.ticketId}]`:"";return `${o}:${l}${p} \u2014 Skipped`}let r=new Map;for(let l of Object.values(e.votes))K(l)||r.set(l,(r.get(l)??0)+1);let i=[...r.entries()].toSorted((l,p)=>p[1]-l[1]||l[0].localeCompare(p[0])).map(([l,p])=>`${l}\xD7${p}`).join(", "),s=Object.values(e.votes).filter(K).length,a=s>0?` (${s} abstained)`:"",d=e.title?` ${e.title}`:"",u=e.ticketId?` [${e.ticketId}]`:"",c=e.timerStartedAt!==void 0&&e.status==="revealed"&&e.terminalAt!==void 0?` \u2014 ${to(e.timerStartedAt,e.terminalAt)}`:"";return `${o}:${d}${u} \u2014 ${i||"(no votes)"}${a}${c}`}function Tr({projection:e,onlineIds:t,isHost:n,participantId:o,rounds:r,currentRound:i,settingsOpen:s,onStartRound:a,onNewRound:d,onRevote:u,onOpenSettings:c,onHandoffHost:l,onEndSession:p,onShare:A,shareOpen:N,onSetShareOpen:R,roomCode:T,confirmingQuit:U,myRole:f,onToggleRole:h,roundTitlePromptActive:b,roundTitleInput:y,onRoundTitleChange:O,onRoundTitleSubmit:C,onRoundTitleCancel:M,roundTicketIdPromptActive:I,roundTicketIdInput:P,onRoundTicketIdChange:ue,onRoundTicketIdSubmit:re,onRoundTicketIdCancel:ie,descriptorPromptActive:V,descriptorInput:z,onDescriptorChange:X,onDescriptorSubmit:ve,onDescriptorCancel:ge,onEditDescriptor:m,canExport:x,onExportResults:E,onAgendaAdd:Y,agendaAddPromptActive:pe,agendaAddTitleInput:rt,onAgendaAddTitleChange:un,onAgendaAddTitleSubmit:qe,onAgendaAddTitleCancel:It,agendaAddTicketIdPromptActive:Ce,agendaAddTicketIdInput:pn,onAgendaAddTicketIdChange:ze,onAgendaAddTicketIdSubmit:Xe,onAgendaAddTicketIdCancel:Pe}){let[Q,Z]=nn.useState("idle"),[he,be]=nn.useState(null),[it,se]=nn.useState(false),[fe,De]=nn.useState(false);useEffect(()=>{n||(Z("idle"),be(null),se(false),De(false));},[n]),useInput(w=>{if(w==="c"||w==="C"){R(true);return}if(w==="w"||w==="W"){h();return}if((w==="x"||w==="X")&&x){E();return}if(n){if(w==="a"||w==="A"){Y();return}(w==="e"||w==="E")&&c(),(w==="s"||w==="S")&&a(),(w==="h"||w==="H")&&Z("picking"),(w==="m"||w==="M")&&se(true),i!==null&&de(i.status)&&((w==="n"||w==="N")&&d(),(w==="v"||w==="V")&&i.status!=="skipped"&&u(),(w==="t"||w==="T")&&m());}},{isActive:!s&&!U&&Q==="idle"&&!b&&!I&&!it&&!fe&&!N&&!V&&!pe&&!Ce}),useInput((w,ee)=>{w==="y"||w==="Y"?(p(),De(false)):(w==="n"||w==="N"||ee.escape)&&De(false);},{isActive:fe});let Ie=e.participants.filter(w=>w.id!==o&&t.has(w.id));useInput(w=>{if(Q==="picking"){let ee=parseInt(w,10);!isNaN(ee)&&ee>=1&&ee<=Ie.length?(be(Ie[ee-1].id),Z("confirming")):(w==="Escape"||w==="q"||w==="Q")&&Z("idle");}},{isActive:Q==="picking"}),useInput(w=>{Q==="confirming"&&he&&(w==="y"||w==="Y"?(l(he),Z("idle"),be(null)):(w==="n"||w==="N"||w==="Escape")&&(Z("idle"),be(null)));},{isActive:Q==="confirming"});let Oe=r.length>0,At=r.filter(w=>de(w.status)),st=i!==null?At.slice(0,-1):At;return it?jsx(vr,{onPick:w=>{se(false),w==="end-session"&&De(true);},onClose:()=>se(false)}):N?jsx(tn,{roomCode:T,onPick:w=>{R(false),A(w);},onClose:()=>R(false)}):jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:Oe?"Session":"Waiting for participants..."}),!Oe&&jsx(Text,{dimColor:true,children:"No rounds started yet."}),jsx(en,{participants:e.participants,onlineIds:t,hostId:e.settings.hostParticipantId,votes:{},revealed:false,participantId:o}),e.agenda.length>0&&jsx(Ls,{items:e.agenda,nextPending:Le(e)}),i!==null&&de(i.status)&&jsx(Us,{projection:e,round:i,rounds:r}),st.length>0&&jsxs(Box,{flexDirection:"column",children:[jsx(Text,{dimColor:true,children:"\u2500\u2500 History \u2500\u2500"}),st.map(w=>{let ee=r.indexOf(w)+1;return jsx(Text,{dimColor:true,children:Rr(w,ee,r)},w.id)})]}),Q==="picking"&&Ie.length>0&&jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{children:"Hand off to:"}),Ie.map((w,ee)=>jsxs(Text,{children:["[",ee+1,"] ",w.displayName]},w.id)),jsx(Text,{dimColor:true,children:"[q] Cancel"})]}),Q==="picking"&&Ie.length===0&&jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{dimColor:true,children:"No other online participants"}),jsx(Text,{dimColor:true,children:"[q] Cancel"})]}),Q==="confirming"&&he&&jsx(Box,{flexDirection:"column",children:jsxs(Text,{children:["Hand off to ",e.participants.find(w=>w.id===he)?.displayName,"? [y/n]"]})}),b&&jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{gap:1,children:[jsx(Text,{children:"Round title (optional, Enter to skip):"}),jsx(j,{value:y,onChange:O,onSubmit:C,onCancel:M,placeholder:"Enter to skip",isActive:b})]}),jsx(Text,{dimColor:true,children:"[Esc] Cancel"})]}),I&&jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{gap:1,children:[jsx(Text,{children:"Ticket ID (optional, Enter to skip):"}),jsx(j,{value:P,onChange:ue,onSubmit:re,onCancel:ie,placeholder:"e.g. PROJ-1234",isActive:I})]}),jsx(Text,{dimColor:true,children:"[Esc] Cancel"})]}),V&&jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{gap:1,children:[jsx(Text,{children:"Edit round title:"}),jsx(j,{value:z,onChange:X,onSubmit:ve,onCancel:ge,placeholder:"Enter to save",isActive:V})]}),jsx(Text,{dimColor:true,children:"[Esc] Cancel \xB7 empty submit cancels"})]}),fe&&jsxs(Box,{children:[jsx(Text,{color:"red",children:"End session for everyone? This cannot be undone. "}),jsx(Text,{dimColor:true,children:"y/n [Esc] Cancel"})]}),pe&&jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{gap:1,children:[jsx(Text,{children:"Agenda title (optional, Enter to skip):"}),jsx(j,{value:rt,onChange:un,onSubmit:qe,onCancel:It,placeholder:"Enter to skip",isActive:pe})]}),jsx(Text,{dimColor:true,children:"[Esc] Cancel"})]}),Ce&&jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{gap:1,children:[jsx(Text,{children:"Agenda ticket ID (optional, Enter to skip):"}),jsx(j,{value:pn,onChange:ze,onSubmit:Xe,onCancel:Pe,placeholder:"e.g. PROJ-1234",isActive:Ce})]}),jsx(Text,{dimColor:true,children:"[Esc] Cancel"})]}),Q==="idle"&&!b&&!I&&!V&&!fe&&!pe&&!Ce&&jsxs(Box,{gap:2,children:[n?jsx(Fragment,{children:i!==null&&de(i.status)?jsxs(Fragment,{children:[i.status!=="skipped"&&jsx(Text,{color:"yellow",children:"[v] Revote"}),jsx(Text,{color:"yellow",children:"[n] Next"}),jsx(Text,{color:"yellow",children:"[t] Edit title"}),jsx(Text,{color:"yellow",children:"[h] Handoff"}),jsx(Text,{color:"yellow",children:"[e] Settings"}),jsx(Text,{color:"yellow",children:"[c] Share"}),x&&jsx(Text,{color:"yellow",children:"[x] Export"}),jsxs(Text,{color:"yellow",children:["[w] ",f==="viewer"?"Vote":"Observe"]}),jsx(Text,{color:"yellow",children:"[m] Menu"})]}):jsxs(Fragment,{children:[jsx(Text,{color:"yellow",children:"[s] Start round"}),jsx(Text,{color:"yellow",children:"[a] Agenda"}),jsx(Text,{color:"yellow",children:"[h] Handoff"}),jsx(Text,{color:"yellow",children:"[e] Settings"}),jsx(Text,{color:"yellow",children:"[c] Share"}),x&&jsx(Text,{color:"yellow",children:"[x] Export"}),jsxs(Text,{color:"yellow",children:["[w] ",f==="viewer"?"Vote":"Observe"]}),jsx(Text,{color:"yellow",children:"[m] Menu"})]})}):jsxs(Fragment,{children:[jsx(Text,{dimColor:true,children:"Waiting for host to start a round..."}),jsx(Text,{children:"[c] Share"}),x&&jsx(Text,{color:"yellow",children:"[x] Export"}),jsxs(Text,{color:"yellow",children:["[w] ",f==="viewer"?"Vote":"Observe"]})]}),jsx(Text,{children:"[q] Quit"})]})]})}function Us({projection:e,round:t,rounds:n}){let o=n.indexOf(t)+1,r=Ir(t,o,n);if(t.status==="skipped")return jsx(Box,{flexDirection:"column",gap:1,children:jsx(Text,{bold:true,children:r})});let i=Ar(t.votes),s=new Map(e.participants.map(p=>[p.id,p.displayName])),a=t.timerStartedAt!==void 0&&t.status==="revealed"&&t.terminalAt!==void 0?to(t.timerStartedAt,t.terminalAt):null,d=Object.entries(t.votes),u=d.filter(([,p])=>!K(p)),c=d.filter(([,p])=>K(p)).map(([p])=>p),l=u[0]?.[1];return jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:r}),An(t)&&l!==void 0&&jsxs(Text,{bold:true,color:"green",children:["Consensus! Everyone voted ",l]}),jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{gap:2,children:[jsx(Text,{bold:true,underline:true,children:"Name".padEnd(20)}),jsx(Text,{bold:true,underline:true,children:"Estimate".padEnd(10)})]}),u.map(([p,A])=>jsxs(Box,{gap:2,children:[jsx(Text,{children:(s.get(p)??p).padEnd(20)}),jsx(Text,{color:"cyan",bold:true,children:A.padEnd(10)})]},p)),c.map(p=>jsxs(Box,{gap:2,children:[jsx(Text,{dimColor:true,children:(s.get(p)??p).padEnd(20)}),jsx(Text,{dimColor:true,children:"(abstained)".padEnd(10)})]},p)),e.participants.filter(p=>!(p.id in t.votes)).map(p=>jsxs(Box,{gap:2,children:[jsx(Text,{dimColor:true,children:p.displayName.padEnd(20)}),jsx(Text,{dimColor:true,children:"(no vote)".padEnd(10)})]},p.id))]}),jsxs(Box,{gap:2,children:[jsxs(Text,{children:["Avg: ",jsx(Text,{bold:true,children:i.average})]}),jsxs(Text,{children:["Med: ",jsx(Text,{bold:true,children:i.median})]}),jsxs(Text,{children:["Agreement: ",jsx(Text,{bold:true,children:i.agreement})]}),a!==null&&jsxs(Text,{dimColor:true,children:["\u23F1 ",a]})]})]})}var Bs={pending:"\u2022",consumed:"\u2713",skipped:"~",cancelled:"\u2717"},Hs={consumed:"green",skipped:"yellow",cancelled:"red"};function Ls({items:e,nextPending:t}){let n=e.filter(o=>o.state!=="cancelled");return jsxs(Box,{flexDirection:"column",children:[jsx(Text,{dimColor:true,children:"\u2500\u2500 Agenda \u2500\u2500"}),n.map(o=>{let r=Bs[o.state]??"?",i=Hs[o.state],s=t!==null&&o.id===t.id,a=[o.ticketId?`[${o.ticketId}]`:"",o.title??""].filter(Boolean).join(" ").trim()||o.id;return jsxs(Box,{gap:1,children:[i!==void 0?jsx(Text,{color:i,children:r}):jsx(Text,{children:r}),i!==void 0?jsx(Text,{color:i,children:a}):jsx(Text,{children:a}),s&&jsx(Text,{color:"cyan",children:"(next)"})]},o.id)}),n.length===0&&jsx(Text,{dimColor:true,children:"No pending items."})]})}function Nr({scale:e,selected:t,onSelect:n,onClear:o,disabled:r}){let[i,s]=useState(0);return useInput((a,d)=>{if(!r)if(d.leftArrow)s(u=>Math.max(0,u-1));else if(d.rightArrow)s(u=>Math.min(e.cards.length-1,u+1));else if(d.return){let u=e.cards[i];u===t?o():n(u);}else (d.backspace||d.delete)&&o();}),jsxs(Box,{flexDirection:"column",gap:0,children:[jsx(Box,{gap:1,children:e.cards.map((a,d)=>{let u=d===i,c=a===t;return jsx(Text,{inverse:u,bold:c,...c&&{color:"cyan"},children:c?`[${a}]`:` ${a} `},a)})}),jsx(Text,{dimColor:true,children:" \u2190\u2192 navigate \u23CE select \u232B clear"})]})}function Ys(e){let t=Math.floor(e/1e3),n=Math.floor(t/60),o=t%60;return `${n}:${o.toString().padStart(2,"0")}`}function Pr({projection:e,round:t,onlineIds:n,isHost:o,myId:r,myRole:i,elapsedMs:s,roomCode:a,shareOpen:d,settingsOpen:u,onVote:c,onClearVote:l,onReveal:p,onSkip:A,onDiscard:N,onToggleRole:R,onShare:T,onSetShareOpen:U,onOpenSettings:f,confirmingQuit:h}){let b=t.votes[r],y=b!==void 0&&K(b);if(useInput(P=>{if(P==="e"||P==="E"){f();return}if(P==="c"||P==="C"){U(true);return}if(i==="voter"&&(P==="a"||P==="A")){y?l():c(Et);return}o&&(P==="r"||P==="R")&&p(),o&&(P==="s"||P==="S")&&A(),o&&(P==="d"||P==="D")&&N(),(P==="w"||P==="W")&&R();},{isActive:!h&&!u&&!d}),d)return jsx(tn,{roomCode:a,onPick:P=>{U(false),T(P);},onClose:()=>U(false)});let O=b,C=e.rounds.indexOf(t)+1,M=t.title?` \u2014 ${t.title}`:"",I=t.ticketId?` [${t.ticketId}]`:"";return jsxs(Box,{flexDirection:"column",gap:1,children:[jsxs(Box,{gap:2,children:[jsxs(Text,{bold:true,children:["Round ",C,M,I]}),s!==void 0&&jsxs(Text,{dimColor:true,children:["\u23F1 ",Ys(s)]})]}),jsxs(Box,{gap:4,children:[jsx(en,{participants:e.participants,onlineIds:n,hostId:e.settings.hostParticipantId,votes:t.votes,revealed:false}),i==="viewer"?jsx(Box,{flexDirection:"column",children:jsx(Text,{dimColor:true,children:"You're observing"})}):jsxs(Box,{flexDirection:"column",gap:1,children:[y&&jsx(Text,{dimColor:true,children:"(abstaining this round \u2014 press [a] to vote)"}),jsx(Nr,{scale:t.scale,selected:y?void 0:O,onSelect:c,onClear:l,disabled:h||y})]})]}),jsxs(Box,{gap:2,children:[o&&jsx(Text,{color:"yellow",children:"[r] Reveal"}),o&&jsx(Text,{color:"yellow",children:"[s] Skip"}),o&&jsx(Text,{color:"yellow",children:"[d] Discard"}),i==="voter"&&jsxs(Text,{color:"yellow",children:["[a] ",y?"Vote":"Abstain"]}),jsxs(Text,{color:"yellow",children:["[w] ",i==="viewer"?"Vote":"Observe"]}),jsx(Text,{children:"[e] Settings"}),jsx(Text,{children:"[c] Share"}),jsx(Text,{children:"[q] Quit"})]})]})}var Ws=3e3;function sn(e=Ws){let[t,n]=useState(null),o=useRef(null),r=useCallback(()=>{o.current!==null&&(clearTimeout(o.current),o.current=null);},[]),i=useCallback(a=>{r(),n(a),o.current=setTimeout(()=>{n(null),o.current=null;},e);},[r,e]),s=useCallback(()=>{r(),n(null);},[r]);return useEffect(()=>()=>{r();},[r]),{notice:t,show:i,dismiss:s}}function Xs(e){let t=W(e);return !t||de(t.status)?"lobby":"voting"}function dn({session:e,participantId:t,displayName:n,accessMode:o,presetOverrides:r,customScales:i}){let{exit:s}=useApp(),[a,d]=useState(e.projection()),[u,c]=useState("connecting"),[l,p]=useState(e.onlineIds()),[A,N]=useState(),[R,T]=useState(false),[U,f]=useState(o==="password"?"password":"open"),[h,b]=useState(n),[y,O]=useState(false),[C,M]=useState(false),[I,P]=useState(""),[ue,re]=useState(false),[ie,V]=useState(""),[z,X]=useState(),[ve,ge]=useState(false),[m,x]=useState(""),[E,Y]=useState(null),[pe,rt]=useState(false),[un,qe]=useState(""),[It,Ce]=useState(false),[pn,ze]=useState(""),[Xe,Pe]=useState(),[Q,Z]=useState(),he=sn(3e3),[be,it]=useState(false),se=sn(3e3),fe=sn(3e3);useEffect(()=>{let v=e.onChange(()=>{d(e.projection()),p(e.onlineIds());}),B=e.onStatusChange(c),Qe=e.onHostChange(Rt=>{let yi=e.projection().participants.find(Ci=>Ci.id===Rt),vi=Rt===t?"You are now the host":`${yi?.displayName||"Unknown"} is now the host`;he.show(vi);}),mn=setInterval(()=>{p(e.onlineIds());let Rt=e.projection(),Tt=W(Rt);Tt?.timerStartedAt!==void 0&&Ht(Tt.status)?N(Date.now()-Tt.timerStartedAt):N(void 0);},1e3);return ()=>{v(),B(),Qe(),clearInterval(mn);}},[e,t,he.show]),useInput(v=>{(v==="q"||v==="Q")&&O(true);},{isActive:!R&&!y&&!C&&!ue&&!ve&&!be&&!pe&&!It}),useInput((v,B)=>{v==="y"||v==="Y"?(e.disconnect(),s()):(v==="n"||v==="N"||B.escape)&&O(false);},{isActive:y});let De=Xs(a),Ie=W(a),Oe=a.settings.hostParticipantId===t,At=a.participants.find(v=>v.id===t),st=Ae(At??{}),w=useCallback(()=>{let v=Wt(Le(a));P(v.title),Z(v.agendaItemId),M(true);},[a]),ee=useCallback(v=>{M(false),P(""),X(Kn(v));let B=Wt(Le(a));V(B.ticketId),re(true);},[a]),Jr=useCallback(()=>{M(false),P(""),X(void 0),Z(void 0);},[]),Gr=useCallback(v=>{re(false),V("");let[B,Qe,mn]=dr(z,v,Q);e.newRound(B,Qe,mn),X(void 0),Z(void 0);},[e,z,Q]),Wr=useCallback(()=>{re(false),V(""),X(void 0),Z(void 0);},[]),qr=useCallback(()=>{let v=e.current();!v||v.status!=="revealed"||(Y(v.id),x(v.title??""),ge(true));},[e]),zr=useCallback(v=>{let B=E;if(ge(false),Y(null),!B)return;let Qe=v.trim();Qe!==""&&e.updateRoundDescriptor(B,{title:Qe});},[e,E]),Xr=useCallback(()=>{ge(false),Y(null);},[]),Qr=useCallback(v=>{e.vote(v);},[e]),Zr=useCallback(()=>{e.unvote();},[e]),ei=useCallback(()=>{e.reveal();},[e]),ti=useCallback(()=>{e.skip();},[e]),ni=useCallback(()=>{e.discardCurrentRound();},[e]),oi=useCallback(()=>{let v=Wt(Le(a));P(v.title),Z(v.agendaItemId),M(true);},[a]),ri=useCallback(()=>{e.revote();},[e]),so=useCallback(()=>{e.toggleRole();},[e]),ii=useCallback(v=>{e.updateName(v);},[e]),si=useCallback(v=>{e.updateScale(v);},[e]),ai=useCallback(v=>{e.updateDisplayName(v),b(v);},[e]),di=useCallback(async(v,B)=>{await e.updateAccess(v,B),f(v);},[e]),ci=useCallback(v=>{try{e.handoffHost(v);}catch(B){console.error(`Handoff failed: ${B instanceof Error?B.message:String(B)}`);}},[e]),ao=useCallback(()=>{T(true);},[]),li=useCallback(()=>{T(false);},[]),ui=useCallback(()=>{e.endSessionForEveryone();},[e]),co=useCallback(async v=>{let B=v==="code"?Kt(e.roomCode):v==="url"?Jt(e.roomCode):Gt(e.roomCode);try{await Or.write(B),se.show("Copied!");}catch{se.show(`Copy failed \u2014 ${B}`);}},[e.roomCode,se]),fn=a.rounds.filter(v=>de(v.status)),pi=fn.length>0?fn.at(-1):null,fi=fn.length>0,mi=useCallback(()=>Cr(a,v=>Or.write(v),fe.show),[a,fe.show]),gi=useCallback(()=>{qe(""),rt(true);},[]),hi=useCallback(v=>{rt(false),qe("");let B=v.trim()===""?void 0:v.trim();Pe(B),ze(""),Ce(true);},[]),Si=useCallback(()=>{rt(false),qe(""),Pe(void 0);},[]),xi=useCallback(v=>{Ce(false),ze("");let B=v.trim()===""?void 0:v.trim();if(!Xe&&!B){Pe(void 0);return}pt(e.doc,{...Xe!==void 0&&{title:Xe},...B!==void 0&&{ticketId:B},createdAt:Date.now()}),Pe(void 0);},[e.doc,Xe]),wi=useCallback(()=>{Ce(false),ze(""),Pe(void 0);},[]);return jsxs(Box,{flexDirection:"column",children:[jsx(ur,{roomCode:e.roomCode,sessionName:a.settings.name,status:u,isHost:Oe}),he.notice&&jsx(Box,{paddingX:1,children:jsx(Text,{color:"yellow",children:he.notice})}),se.notice&&jsx(Box,{paddingX:1,children:jsx(Text,{color:se.notice.startsWith("Copy failed")?"red":"green",children:se.notice})}),fe.notice&&jsx(Box,{paddingX:1,children:jsx(Text,{color:fe.notice.startsWith("Clipboard write failed")?"red":"green",children:fe.notice})}),R?jsx(wr,{sessionName:a.settings.name,displayName:h,currentScale:a.settings.defaultScale,accessMode:U,presetOverrides:r,customScales:i,isHost:Oe,onChangeName:ii,onChangeScale:si,onChangeDisplayName:ai,onChangeAccess:di,onClose:li}):De==="lobby"?jsx(Tr,{projection:a,onlineIds:l,isHost:Oe,participantId:t,rounds:a.rounds,currentRound:pi,settingsOpen:R,onStartRound:w,onNewRound:oi,roundTitlePromptActive:C,roundTitleInput:I,onRoundTitleChange:P,onRoundTitleSubmit:ee,onRoundTitleCancel:Jr,roundTicketIdPromptActive:ue,roundTicketIdInput:ie,onRoundTicketIdChange:V,onRoundTicketIdSubmit:Gr,onRoundTicketIdCancel:Wr,onRevote:ri,onOpenSettings:ao,onHandoffHost:ci,onEndSession:ui,onShare:co,shareOpen:be,onSetShareOpen:it,roomCode:e.roomCode,confirmingQuit:y,myRole:st,onToggleRole:so,descriptorPromptActive:ve,descriptorInput:m,onDescriptorChange:x,onDescriptorSubmit:zr,onDescriptorCancel:Xr,onEditDescriptor:qr,canExport:fi,onExportResults:mi,onAgendaAdd:gi,agendaAddPromptActive:pe,agendaAddTitleInput:un,onAgendaAddTitleChange:qe,onAgendaAddTitleSubmit:hi,onAgendaAddTitleCancel:Si,agendaAddTicketIdPromptActive:It,agendaAddTicketIdInput:pn,onAgendaAddTicketIdChange:ze,onAgendaAddTicketIdSubmit:xi,onAgendaAddTicketIdCancel:wi}):De==="voting"&&Ie?jsx(Pr,{projection:a,round:Ie,onlineIds:l,isHost:Oe,myId:t,myRole:st,elapsedMs:A,onVote:Qr,onClearVote:Zr,onReveal:ei,onSkip:ti,onDiscard:ni,onToggleRole:so,onShare:co,onSetShareOpen:it,shareOpen:be,settingsOpen:R,onOpenSettings:ao,roomCode:e.roomCode,confirmingQuit:y}):null,y&&jsx(Box,{children:jsx(Text,{dimColor:true,children:"Leave session? y/n"})})]})}function Mr({presetOverrides:e,customScales:t}){let{exit:n}=useApp(),[o,r]=useState("main-menu"),[i,s]=useState(Fe()),[a,d]=useState(i.displayName??""),[u,c]=useState(i.relayUrl??""),[l,p]=useState(i.defaultSessionName??""),[A,N]=useState(i.avatarColor?.startsWith("#")?i.avatarColor:""),[R,T]=useState(t??[]),[U,f]=useState(e??{});useInput(m=>{(m==="q"||m==="Q")&&n();},{isActive:o==="main-menu"});let h=useMemo(()=>_t(U,R),[U,R]),b=i.defaultScale,y=b?h.find(m=>m.id===b):void 0,O=[{label:"Display name",value:"display-name",detail:`[${i.displayName??"(none)"}]`},{label:"Relay URL",value:"relay-url",detail:`[${i.relayUrl??"(none)"}]`},{label:"Default scale",value:"default-scale",detail:`[${y?je(y.id,R):"(none)"}]`},{label:"Default session name",value:"default-session-name",detail:`[${i.defaultSessionName??"(none)"}]`},{label:"Default password",value:"default-password",detail:`[${i.defaultPassword?"on":"off"}]`},{label:"Avatar color",value:"avatar-color",detail:`[${oa(i.avatarColor)}]`}];function C(m){m==="display-name"?(d(i.displayName??""),r("editing-display-name")):m==="relay-url"?(c(i.relayUrl??""),r("editing-relay-url")):m==="default-scale"?r("picking-scale"):m==="default-session-name"?(p(i.defaultSessionName??""),r("editing-session-name")):m==="default-password"?r("picking-default-password"):m==="avatar-color"&&r("picking-avatar-color");}function M(m){if(m==="custom-hex"){N(i.avatarColor?.startsWith("#")?i.avatarColor:""),r("editing-avatar-hex");return}if(Me(m)===null){r("main-menu");return}s({...i,avatarColor:m}),F({avatarColor:m}),r("main-menu");}function I(m){let x=m.trim();if(x.length===0){r("picking-avatar-color");return}let E=x.startsWith("#")?x.toLowerCase():`#${x.toLowerCase()}`;Me(E)!==null&&(s({...i,avatarColor:E}),F({avatarColor:E}),r("main-menu"));}function P(m){let x=m.trim();if(x.length>0){let E={...i,displayName:x};s(E),F({displayName:x});}r("main-menu");}function ue(m){let x=m.trim();if(x.length>0){let E={...i,relayUrl:x};s(E),F({relayUrl:x});}r("main-menu");}function re(m){let x=m.trim(),E=x.length>0?{...i,defaultSessionName:x}:{...i};x.length===0?(delete E.defaultSessionName,s(E),mt({defaultSessionName:""})):(s(E),F({defaultSessionName:x})),r("main-menu");}function ie(m){let x=m.length>0?{...i,defaultScale:m}:{...i};m.length===0?(delete x.defaultScale,s(x),mt({defaultScale:""})):(s(x),F({defaultScale:m})),r("main-menu");}function V(m,x){let E={...U};x.length===0?delete E[m]:E[m]=x,f(E),F({presetOverrides:Object.keys(E).length>0?E:void 0});}function z(m){let x=m==="on",E={...i,defaultPassword:x};s(E),F({defaultPassword:x}),r("main-menu");}function X(m,x){let E=`custom-${randomUUID()}`,Y=[...R,{id:E,label:m,cards:x}];T(Y),s({...i,customScales:Y}),F({customScales:Y});}function ve(m,x,E){let Y=R.map(pe=>pe.id===m?{id:m,label:x,cards:E}:pe);T(Y),s({...i,customScales:Y}),F({customScales:Y});}function ge(m){let x=R.filter(Y=>Y.id!==m);T(x);let E={...i,customScales:x};i.defaultScale===m?(E.defaultScale="fibonacci",F({customScales:x,defaultScale:"fibonacci"})):F({customScales:x}),s(E);}if(o==="main-menu")return jsx(me,{title:"\u2500\u2500 Config Settings \u2500\u2500",items:O,onSelect:C,onClose:()=>n()});if(o==="editing-display-name")return jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Config Settings \u2500\u2500"}),jsx(Text,{children:"Display name: "}),jsx(j,{value:a,onChange:d,onSubmit:P,onCancel:()=>r("main-menu"),placeholder:"(required)",isActive:true}),jsx(Text,{dimColor:true,children:"\u23CE confirm esc back"})]});if(o==="editing-relay-url")return jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Config Settings \u2500\u2500"}),jsx(Text,{children:"Relay URL: "}),jsx(j,{value:u,onChange:c,onSubmit:ue,onCancel:()=>r("main-menu"),placeholder:"(required)",isActive:true}),jsx(Text,{dimColor:true,children:"\u23CE confirm esc back"})]});if(o==="editing-session-name")return jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Config Settings \u2500\u2500"}),jsx(Text,{children:"Default session name: "}),jsx(j,{value:l,onChange:p,onSubmit:re,onCancel:()=>r("main-menu"),placeholder:"(leave empty to clear)",isActive:true}),jsx(Text,{dimColor:true,children:"\u23CE confirm esc back"})]});if(o==="picking-scale"){let m=[{id:"",cards:[]},...h];return jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Config Settings \u2500\u2500"}),jsx(Xt,{scales:m,selectedScaleId:b??"",presetOverrides:U,customScales:R,onSelect:ie,onOverrideChange:V,onCustomScaleCreate:X,onCustomScaleEdit:ve,onCustomScaleDelete:ge,onClose:()=>r("main-menu"),showNoneOption:true})]})}if(o==="picking-avatar-color"){let m=at.map(x=>({label:Ze[x].label,value:x,detail:i.avatarColor===x?"[current]":Ze[x].base}));return m.push({label:"Custom hex\u2026",value:"custom-hex",detail:i.avatarColor?.startsWith("#")?`[${i.avatarColor}]`:void 0}),jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Config Settings \u2500\u2500"}),jsx(me,{title:"Avatar color:",items:m,onSelect:M,onClose:()=>r("main-menu")})]})}if(o==="editing-avatar-hex")return jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Config Settings \u2500\u2500"}),jsx(Text,{children:"Custom hex color: "}),jsx(j,{value:A,onChange:N,onSubmit:I,onCancel:()=>r("picking-avatar-color"),placeholder:"#rrggbb",isActive:true}),jsx(Text,{dimColor:true,children:"\u23CE confirm esc back"})]});if(o==="picking-default-password"){let m=[{label:"On",value:"on",detail:i.defaultPassword?"[current]":void 0},{label:"Off",value:"off",detail:i.defaultPassword?void 0:"[current]"}];return jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Config Settings \u2500\u2500"}),jsx(me,{title:"Default password:",items:m,onSelect:z,onClose:()=>r("main-menu")})]})}return jsx(Box,{})}function oa(e){return e?e.startsWith("#")?e:at.includes(e)?Ze[e].label:e:"(auto)"}var ia={pending:"\u2022",consumed:"\u2713",skipped:"~",cancelled:"\u2717"};function sa(e){let t=ia[e.state]??"?",n=[];e.ticketId&&n.push(`[${e.ticketId}]`),e.title&&n.push(e.title);let o=n.join(" ")||e.id;return `${t} ${o}`}async function Ct(e){let t=new $e.Doc,n=new Awareness(t);Ue(t,{participantId:e.participantId,displayName:e.displayName}),n.setLocalStateField("participantId",e.participantId);let o=et({doc:t,awareness:n,roomCode:e.roomCode,roomUuid:e.roomUuid,participantId:e.participantId,relayUrl:e.relayUrl,...e.passwordHash!==void 0&&{passwordHash:e.passwordHash}});return await new Promise(r=>{let i=setTimeout(r,2e3),s=o.onStatusChange(a=>{a==="connected"&&setTimeout(()=>{clearTimeout(i),s(),r();},200);});}),{doc:t,disconnect:()=>o.disconnect()}}async function bt(){let e=Ft();e.length===0&&(console.error("No active session. Join a room first with: hnch join <code>"),process.exit(1));let t=e[0];return {roomCode:t.roomCode,roomUuid:t.roomUuid,...t.passwordHash!==void 0&&{passwordHash:t.passwordHash}}}async function Ur(e){!e.title?.trim()&&!e.ticket?.trim()&&(console.error("At least one of --title or --ticket is required"),process.exit(1));let t=await ce(),n=await bt();try{await le(t.relayUrl,n.roomCode);}catch{console.error(`Room ${n.roomCode} not found on relay \u2014 session may have expired.`),process.exit(1);}let{doc:o,disconnect:r}=await Ct({relayUrl:t.relayUrl,participantId:t.participantId,displayName:t.displayName,roomCode:n.roomCode,roomUuid:n.roomUuid,...n.passwordHash!==void 0&&{passwordHash:n.passwordHash}});try{let i=pt(o,{...e.title?.trim()?{title:e.title.trim()}:{},...e.ticket?.trim()?{ticketId:e.ticket.trim()}:{},...e.description?.trim()?{description:e.description.trim()}:{},createdAt:Date.now()});await new Promise(s=>{setTimeout(s,300);}),console.log(`Added agenda item: ${i}`);}finally{r();}}async function Br(){let e=await ce(),t=await bt();try{await le(e.relayUrl,t.roomCode);}catch{console.error(`Room ${t.roomCode} not found on relay \u2014 session may have expired.`),process.exit(1);}let{doc:n,disconnect:o}=await Ct({relayUrl:e.relayUrl,participantId:e.participantId,displayName:e.displayName,roomCode:t.roomCode,roomUuid:t.roomUuid,...t.passwordHash!==void 0&&{passwordHash:t.passwordHash}});try{let i=_(n).agenda;if(i.length===0){console.log("No agenda items.");return}i.forEach((s,a)=>{console.log(`${String(a+1).padStart(2)}. ${sa(s)}`);});}finally{o();}}async function Hr(e){let t=await ce(),n=await bt();try{await le(t.relayUrl,n.roomCode);}catch{console.error(`Room ${n.roomCode} not found on relay \u2014 session may have expired.`),process.exit(1);}let{doc:o,disconnect:r}=await Ct({relayUrl:t.relayUrl,participantId:t.participantId,displayName:t.displayName,roomCode:n.roomCode,roomUuid:n.roomUuid,...n.passwordHash!==void 0&&{passwordHash:n.passwordHash}});try{Bt(o,e.id,"skipped",{timestamp:Date.now()}),await new Promise(i=>{setTimeout(i,300);}),console.log(`Skipped agenda item: ${e.id}`);}catch(i){console.error(`Skip failed: ${i instanceof Error?i.message:String(i)}`),process.exit(1);}finally{r();}}async function Lr(e){let t=await ce(),n=await bt();try{await le(t.relayUrl,n.roomCode);}catch{console.error(`Room ${n.roomCode} not found on relay \u2014 session may have expired.`),process.exit(1);}let{doc:o,disconnect:r}=await Ct({relayUrl:t.relayUrl,participantId:t.participantId,displayName:t.displayName,roomCode:n.roomCode,roomUuid:n.roomUuid,...n.passwordHash!==void 0&&{passwordHash:n.passwordHash}});try{Bt(o,e.id,"cancelled",{timestamp:Date.now()}),await new Promise(i=>{setTimeout(i,300);}),console.log(`Cancelled agenda item: ${e.id}`);}catch(i){console.error(`Cancel failed: ${i instanceof Error?i.message:String(i)}`),process.exit(1);}finally{r();}}async function _r(e){let t=await ce(),n=await bt();try{await le(t.relayUrl,n.roomCode);}catch{console.error(`Room ${n.roomCode} not found on relay \u2014 session may have expired.`),process.exit(1);}let{doc:o,disconnect:r}=await Ct({relayUrl:t.relayUrl,participantId:t.participantId,displayName:t.displayName,roomCode:n.roomCode,roomUuid:n.roomUuid,...n.passwordHash!==void 0&&{passwordHash:n.passwordHash}});try{Tn(o,e.id,e.before,e.after),await new Promise(i=>{setTimeout(i,300);}),console.log(`Reordered agenda item: ${e.id}`);}catch(i){console.error(`Move failed: ${i instanceof Error?i.message:String(i)}`),process.exit(1);}finally{r();}}async function io(){return new Promise(e=>{let t=createInterface({input:process.stdin,output:process.stderr});process.stderr.write("Password: "),t.question("",n=>{t.close(),e(n);});})}async function ca(e){let t=await ce(),n=e.scale??t.defaultScale??"fibonacci",o=e.name??t.defaultSessionName,r=e.password??t.defaultPassword??false,i;r&&(i=await io());let s=Lt(n,t.presetOverrides,t.customScales);if(!s){let l=Object.keys(ae).join(", ");console.error(`Unknown or fully-disabled scale: "${n}". Builtin IDs: ${l}`),process.exit(1);}let a=await nr({participantId:t.participantId,displayName:t.displayName,relayUrl:t.relayUrl,sessionName:o,password:i,defaultScale:s,...t.avatarColor!==void 0&&{avatarColor:t.avatarColor}}),d;i&&(d=await _e(i,a.roomUuid)),Yn({roomCode:a.roomCode,roomUuid:a.roomUuid,lastSeenAt:Date.now(),...d!==void 0&&{passwordHash:d}}),console.error(`Room created: ${a.roomCode}`),console.error(`Share: hnch join ${a.roomCode}`),console.error("");let{waitUntilExit:u,unmount:c}=render(nn.createElement(dn,{session:a,participantId:t.participantId,displayName:t.displayName,accessMode:i?"password":"open",presetOverrides:t.presetOverrides,customScales:t.customScales}));Yt({doc:a.doc,localParticipantId:t.participantId,onEnded:async l=>{console.error(l.isLocal?"Session ended.":`Session ended by ${l.hostName}.`),c();try{await Se();}catch(p){console.error(`Failed to clear cached session: ${p instanceof Error?p.message:String(p)}`);}a.disconnect(),process.exit(0);}}),await u(),a.disconnect(),Se(),process.exit(0);}async function la(e){let t=await ce(),n=rr(e.code);n===null&&(console.error("invalid room code"),process.exit(1));let o;e.password&&(o=await io());let r=await le(t.relayUrl,n),i;r.accessMode==="password"&&!e.password?i=await io():e.password&&(i=o);let s,a=false,d=await or({participantId:t.participantId,displayName:t.displayName,relayUrl:t.relayUrl,roomCode:n,password:i,...t.avatarColor!==void 0&&{avatarColor:t.avatarColor},onRejection(l){if(l==="unknown-room"){Vt({clearLastSession:Se,logger:console,exit:process.exit});return}l==="room-full"&&(a=true,s?.());}}),u;i&&(u=await _e(i,d.roomUuid)),Yn({roomCode:d.roomCode,roomUuid:d.roomUuid,lastSeenAt:Date.now(),...u!==void 0&&{passwordHash:u}}),console.error(`Joined room: ${d.roomCode}`),console.error("");let c=render(nn.createElement(dn,{session:d,participantId:t.participantId,displayName:t.displayName,accessMode:r.accessMode,presetOverrides:t.presetOverrides,customScales:t.customScales}));s=c.unmount,Yt({doc:d.doc,localParticipantId:t.participantId,onEnded:async l=>{console.error(l.isLocal?"Session ended.":`Session ended by ${l.hostName}.`),s?.();try{await Se();}catch(p){console.error(`Failed to clear cached session: ${p instanceof Error?p.message:String(p)}`);}d.disconnect(),process.exit(0);}}),await c.waitUntilExit(),a&&(console.error("This room is full (max 20 participants)."),d.disconnect(),Se(),process.exit(1)),d.disconnect(),Se(),process.exit(0);}function ua(e,t=Date.now()){let n=t-e,o=Math.floor(n/6e4);return o<60?`${o}m ago`:`${Math.floor(o/60)}h ago`}async function pa(e){return new Promise((t,n)=>{let o=createInterface({input:process.stdin,output:process.stderr}),r=()=>{process.stderr.write(`Select [1-${e}]: `),o.question("",i=>{let s=parseInt(i.trim(),10);Number.isInteger(s)&&s>=1&&s<=e?(o.close(),t(s)):(process.stderr.write(`Invalid choice \u2014 enter a number between 1 and ${e}.
|
|
22
|
+
`),r());});};o.on("close",()=>n(new Error("stdin closed"))),r();})}async function jr(e,t){let n;try{n=await le(e.relayUrl,t.roomCode);}catch(c){if((c instanceof Error?c.message:String(c)).includes("Room not found"))return gt(t.roomUuid),await Vt({clearLastSession:Se,logger:console,exit:process.exit});console.error("Could not reach relay \u2014 try again later."),process.exit(0);}n.accessMode==="password"&&!t.passwordHash&&(console.error(`Password changed \u2014 rejoin with: hnch join ${t.roomCode} --password`),Vn(t.roomUuid),process.exit(0)),console.error(`Rejoining room ${t.roomCode}\u2026`),console.error("");let o=new $e.Doc,r=new Awareness(o);Ue(o,{participantId:e.participantId,displayName:e.displayName,...e.avatarColor!==void 0&&{avatarColor:e.avatarColor}}),r.setLocalStateField("participantId",e.participantId);let i=false,s=false,a,d=et({doc:o,awareness:r,roomCode:t.roomCode,roomUuid:t.roomUuid,participantId:e.participantId,relayUrl:e.relayUrl,passwordHash:t.passwordHash,onRejection(c){if(c==="unknown-room"){gt(t.roomUuid),Vt({clearLastSession:Se,logger:console,exit:process.exit});return}c==="wrong-password"&&(i=true,a?.()),c==="room-full"&&(s=true,a?.());}});Fn({roomCode:d.roomCode,roomUuid:d.roomUuid,lastSeenAt:Date.now(),...t.passwordHash!==void 0&&{passwordHash:t.passwordHash}});let u=render(nn.createElement(dn,{session:d,participantId:e.participantId,displayName:e.displayName,accessMode:n.accessMode,presetOverrides:e.presetOverrides,customScales:e.customScales}));a=u.unmount,Yt({doc:d.doc,localParticipantId:e.participantId,onEnded:async c=>{console.error(c.isLocal?"Session ended.":`Session ended by ${c.hostName}.`),a?.();try{gt(t.roomUuid);}catch(l){console.error(`Failed to clear cached session: ${l instanceof Error?l.message:String(l)}`);}d.disconnect(),process.exit(0);}}),await u.waitUntilExit(),s&&(console.error("This room is full (max 20 participants)."),d.disconnect(),process.exit(1)),i&&(Vn(t.roomUuid),console.error(`Password changed \u2014 rejoin with: hnch join ${t.roomCode} --password`),d.disconnect(),process.exit(0)),d.disconnect(),gt(t.roomUuid),process.exit(0);}async function fa(){let e=await ce(),t=Ft();if(t.length===0&&(console.error("No recent session to resume."),process.exit(0)),t.length===1)return jr(e,t[0]);let n=Date.now();process.stderr.write(`Recent rooms:
|
|
23
|
+
`);for(let[r,i]of t.entries()){let s=ua(i.lastSeenAt,n);process.stderr.write(` ${r+1}. ${i.roomCode} (${s})
|
|
24
24
|
`);}process.stderr.write(`
|
|
25
|
-
`);let o;try{o=await
|
|
25
|
+
`);let o;try{o=await pa(t.length);}catch{console.error("No selection made."),process.exit(1);}return jr(e,t[o-1])}async function ma(e){if(!(e.name!==void 0||e.relayUrl!==void 0||e.scale!==void 0||e.sessionName!==void 0||e.password!==void 0||e.color!==void 0)){let o=await ce(),{waitUntilExit:r}=render(nn.createElement(Mr,{presetOverrides:o.presetOverrides,customScales:o.customScales}));await r(),process.exit(0);}let n={};if(e.name!==void 0&&(n.displayName=e.name),e.relayUrl!==void 0&&(n.relayUrl=e.relayUrl),e.scale!==void 0){if(e.scale!==""){let o=Fe();if(!Lt(e.scale,o.presetOverrides,o.customScales)){console.error(`Unknown scale: "${e.scale}". Builtin IDs: ${Object.keys(ae).join(", ")}`);return}}n.defaultScale=e.scale;}if(e.sessionName!==void 0&&(n.defaultSessionName=e.sessionName),e.password!==void 0&&(n.defaultPassword=e.password),e.color!==void 0){let o=e.color.startsWith("#")||e.color===""?e.color:e.color.toLowerCase();o!==""&&Me(o)===null&&(console.error(`Invalid color: "${e.color}". Pass a palette key or #rrggbb hex literal.`),process.exit(1)),n.avatarColor=o;}mt(n),console.log("Config updated.");}var Kr=aa(hideBin(process.argv)).scriptName("hnch").usage("$0 <command> \u2014 terminal pointing poker").command("create","Create a new room",e=>e.option("name",{type:"string",describe:"Session name"}).option("password",{type:"boolean",describe:"Protect room with a password"}).option("scale",{type:"string",describe:"Estimation scale ID (fibonacci, t-shirt, powers-of-2, linear, risk, or custom-<id>)"}),e=>{ca(e).catch(t=>{console.error(t instanceof Error?t.message:t),process.exit(1);});}).command("join <code>","Join an existing room",e=>e.positional("code",{type:"string",demandOption:true,describe:"6-character room code"}).option("password",{type:"boolean",describe:"Room requires a password",default:false}),e=>{la(e).catch(t=>{console.error(t instanceof Error?t.message:t),process.exit(1);});}).command("resume","Rejoin your last session",e=>e,()=>{fa().catch(e=>{console.error(e instanceof Error?e.message:e),process.exit(1);});}).command("config","View or update CLI config",e=>e.option("name",{type:"string",describe:"Set display name"}).option("relay-url",{type:"string",describe:"Set relay URL"}).option("scale",{type:"string",describe:"Set default estimation scale ID (empty string clears)"}).option("session-name",{type:"string",describe:"Set default session name (empty string clears)"}).option("password",{type:"boolean",describe:"Set default password prompt on (--password) or off (--no-password)"}).option("color",{type:"string",describe:'Set avatar color: a palette key (e.g. "blue", "racing-green") or a #rrggbb hex literal'}),e=>{ma(e).catch(t=>{console.error(t instanceof Error?t.message:t),process.exit(1);});}).command("agenda","Manage the pre-session story agenda",e=>e.command("add","Add an agenda item",t=>t.option("title",{type:"string",describe:"Story title"}).option("ticket",{type:"string",describe:"Issue tracker reference (e.g. PROJ-123)"}).option("description",{type:"string",describe:"Story description"}).check(n=>{if(!n.title?.trim()&&!n.ticket?.trim())throw new Error("At least one of --title or --ticket is required");return true}),t=>{Ur(t).catch(n=>{console.error(n instanceof Error?n.message:n),process.exit(1);});}).command("list","List agenda items in order",t=>t,()=>{Br().catch(t=>{console.error(t instanceof Error?t.message:t),process.exit(1);});}).command("skip <id>","Mark an agenda item as skipped",t=>t.positional("id",{type:"string",demandOption:true,describe:"Agenda item ID"}),t=>{Hr(t).catch(n=>{console.error(n instanceof Error?n.message:n),process.exit(1);});}).command("cancel <id>","Soft-delete (cancel) an agenda item",t=>t.positional("id",{type:"string",demandOption:true,describe:"Agenda item ID"}),t=>{Lr(t).catch(n=>{console.error(n instanceof Error?n.message:n),process.exit(1);});}).command("mv <id>","Reorder an agenda item (--before <id> | --after <id>)",t=>t.positional("id",{type:"string",demandOption:true,describe:"Agenda item ID to move"}).option("before",{type:"string",describe:"sortKey of item that should come before the moved item"}).option("after",{type:"string",describe:"sortKey of item that should come after the moved item"}).check(n=>{if(n.before!==void 0&&n.after!==void 0)throw new Error("--before and --after are mutually exclusive");if(n.before===void 0&&n.after===void 0)throw new Error("Specify either --before <id> or --after <id>");return true}),t=>{_r(t).catch(n=>{console.error(n instanceof Error?n.message:n),process.exit(1);});}).demandCommand(1,"Specify an agenda subcommand: add, list, skip, cancel, mv").strict().help(),()=>{}).demandCommand(1,"Specify a command: create, join, resume, config, or agenda").strict().help(),ro=hideBin(process.argv);(ro.length===0||ro.length===1&&ro[0]==="--")&&(Kr.showHelp(),process.exit(0));Kr.parse();
|