@snagset/server 0.0.3 → 0.1.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.
Files changed (139) hide show
  1. package/README.md +4 -3
  2. package/dist/app.js +167 -30
  3. package/dist/app.js.map +1 -1
  4. package/dist/bin.js +46 -9
  5. package/dist/bin.js.map +1 -1
  6. package/dist/boot.js +105 -54
  7. package/dist/boot.js.map +1 -1
  8. package/dist/config.generated.js +5 -2
  9. package/dist/config.generated.js.map +1 -1
  10. package/dist/db/connect.js +7 -0
  11. package/dist/db/connect.js.map +1 -1
  12. package/dist/db/migrations/0005_studio_reviewers.sql +45 -0
  13. package/dist/db/migrations/0006_instance_settings.sql +69 -0
  14. package/dist/db/migrations/0007_jira_provider.no-txn.sql +13 -0
  15. package/dist/domain.js +129 -0
  16. package/dist/domain.js.map +1 -0
  17. package/dist/instance/settings.js +54 -0
  18. package/dist/instance/settings.js.map +1 -0
  19. package/dist/integrations/github.js +112 -0
  20. package/dist/integrations/github.js.map +1 -0
  21. package/dist/integrations/inbound.js +88 -0
  22. package/dist/integrations/inbound.js.map +1 -0
  23. package/dist/integrations/jira.js +129 -0
  24. package/dist/integrations/jira.js.map +1 -0
  25. package/dist/integrations/linear.js +111 -0
  26. package/dist/integrations/linear.js.map +1 -0
  27. package/dist/integrations/outbox.js +305 -0
  28. package/dist/integrations/outbox.js.map +1 -0
  29. package/dist/integrations/slack.js +135 -0
  30. package/dist/integrations/slack.js.map +1 -0
  31. package/dist/integrations/store.js +101 -0
  32. package/dist/integrations/store.js.map +1 -0
  33. package/dist/mail/index.js +21 -11
  34. package/dist/mail/index.js.map +1 -1
  35. package/dist/mail/resolve.js +80 -0
  36. package/dist/mail/resolve.js.map +1 -0
  37. package/dist/projectCache.js +3 -2
  38. package/dist/projectCache.js.map +1 -1
  39. package/dist/projects.js +8 -2
  40. package/dist/projects.js.map +1 -1
  41. package/dist/routes/account.js +59 -0
  42. package/dist/routes/account.js.map +1 -0
  43. package/dist/routes/activity.js +111 -0
  44. package/dist/routes/activity.js.map +1 -0
  45. package/dist/routes/anchorReports.js +196 -0
  46. package/dist/routes/anchorReports.js.map +1 -0
  47. package/dist/routes/assignees.js +139 -0
  48. package/dist/routes/assignees.js.map +1 -0
  49. package/dist/routes/attachments.js +2 -2
  50. package/dist/routes/attachments.js.map +1 -1
  51. package/dist/routes/bodyLimit.js +60 -0
  52. package/dist/routes/bodyLimit.js.map +1 -0
  53. package/dist/routes/comments.js +27 -17
  54. package/dist/routes/comments.js.map +1 -1
  55. package/dist/routes/cors.js +10 -1
  56. package/dist/routes/cors.js.map +1 -1
  57. package/dist/routes/instance.js +164 -0
  58. package/dist/routes/instance.js.map +1 -0
  59. package/dist/routes/integrations.js +610 -0
  60. package/dist/routes/integrations.js.map +1 -0
  61. package/dist/routes/jobs.js +15 -3
  62. package/dist/routes/jobs.js.map +1 -1
  63. package/dist/routes/mcpTokens.js +119 -0
  64. package/dist/routes/mcpTokens.js.map +1 -0
  65. package/dist/routes/members.js +177 -0
  66. package/dist/routes/members.js.map +1 -0
  67. package/dist/routes/owner.js +64 -7
  68. package/dist/routes/owner.js.map +1 -1
  69. package/dist/routes/sites.js +181 -8
  70. package/dist/routes/sites.js.map +1 -1
  71. package/dist/routes/threads.js +276 -9
  72. package/dist/routes/threads.js.map +1 -1
  73. package/dist/serverless.js +39 -6
  74. package/dist/serverless.js.map +1 -1
  75. package/dist/studioReviewers.js +67 -0
  76. package/dist/studioReviewers.js.map +1 -0
  77. package/dist/vendor/adapters/outbound/sanitise.js +18 -3
  78. package/dist/vendor/types/brief.js +121 -0
  79. package/package.json +1 -1
  80. package/static/dashboard/assets/CompositeItem-CoPuxIvr.js +1 -0
  81. package/static/dashboard/assets/ConfirmDialog-DkCcJwll.js +1 -0
  82. package/static/dashboard/assets/CopyButton-BNa2pLLv.js +1 -0
  83. package/static/dashboard/assets/FieldItemContext-DQXjpFtW.js +1 -0
  84. package/static/dashboard/assets/InstallTag-SOlWl7Hx.js +1 -0
  85. package/static/dashboard/assets/SaveState-CmxB4XyX.js +6 -0
  86. package/static/dashboard/assets/_app-DNkv3HBi.js +1 -0
  87. package/static/dashboard/assets/_app-xVQe811c.js +56 -0
  88. package/static/dashboard/assets/activity-DsMa5Ja6.js +1 -0
  89. package/static/dashboard/assets/arrow-left-vQV4xhAD.js +6 -0
  90. package/static/dashboard/assets/avatar-DuPL6QD_.js +1 -0
  91. package/static/dashboard/assets/badge-BWjiIc8T.js +1 -0
  92. package/static/dashboard/assets/card-BIBfCno8.js +1 -0
  93. package/static/dashboard/assets/check-Dpx6GTdT.js +6 -0
  94. package/static/dashboard/assets/chevron-right-DKIlBUGN.js +6 -0
  95. package/static/dashboard/assets/copy-DCbhEe2L.js +6 -0
  96. package/static/dashboard/assets/createBaseUIEventDetails-C_ZVkrgp.js +1 -0
  97. package/static/dashboard/assets/createLucideIcon-C_IGE4WD.js +36 -0
  98. package/static/dashboard/assets/dialog-BT2uWf4e.js +6 -0
  99. package/static/dashboard/assets/dropdown-menu-DSXzPAwB.js +11 -0
  100. package/static/dashboard/assets/image-off-DGWejLDG.js +6 -0
  101. package/static/dashboard/assets/index-BRTBtV91.css +1 -0
  102. package/static/dashboard/assets/index-D6FWZoJT.js +129 -0
  103. package/static/dashboard/assets/label-9QsSpLMA.js +1 -0
  104. package/static/dashboard/assets/labels--UUyt9uB.js +1 -0
  105. package/static/dashboard/assets/layout-grid-UPGEmEw-.js +6 -0
  106. package/static/dashboard/assets/me-0HQsBXLU.js +1 -0
  107. package/static/dashboard/assets/parts-C29uZ5zo.js +1 -0
  108. package/static/dashboard/assets/plus-BFNS5LcY.js +6 -0
  109. package/static/dashboard/assets/s._site-D6Ep2tdc.js +1 -0
  110. package/static/dashboard/assets/s._site.comments-BRVI5gpJ.js +39 -0
  111. package/static/dashboard/assets/s._site.reviewers-CiEkZnnp.js +1 -0
  112. package/static/dashboard/assets/s._site.settings-BqLGyfEd.js +1 -0
  113. package/static/dashboard/assets/setup-dUMCPWdf.js +1 -0
  114. package/static/dashboard/assets/sign-in-CdRa-bio.js +1 -0
  115. package/static/dashboard/assets/sites-CmbtFKoo.js +1 -0
  116. package/static/dashboard/assets/studio-BHuVXWZh.js +1 -0
  117. package/static/dashboard/assets/studio-BjeTOKda.js +1 -0
  118. package/static/dashboard/assets/studio.index--kuzOs7w.js +1 -0
  119. package/static/dashboard/assets/studio.integrations-Bq6HP80a.js +1 -0
  120. package/static/dashboard/assets/studio.members-8AB1KYsw.js +1 -0
  121. package/static/dashboard/assets/sun-BCiTcgnh.js +16 -0
  122. package/static/dashboard/assets/table-BXmeI_yA.js +1 -0
  123. package/static/dashboard/assets/update-duXzIzFS.js +1 -0
  124. package/static/dashboard/assets/useBaseQuery-Cp9wivVR.js +1 -0
  125. package/static/dashboard/assets/useQuery-BZXZlOqO.js +1 -0
  126. package/static/dashboard/assets/useRender-CO8aPW06.js +1 -0
  127. package/static/dashboard/assets/users-Dvw2FCKM.js +6 -0
  128. package/static/dashboard/assets/welcome-BHKjw20b.js +11 -0
  129. package/static/dashboard/assets/you-RBpAfUMU.js +1 -0
  130. package/static/dashboard/assets/zod-BpyjQIvb.js +1 -0
  131. package/static/dashboard/index.html +17 -2
  132. package/static/widget/snag.capture.js +1 -1
  133. package/static/widget/snag.dock.js +1 -1
  134. package/static/widget/snag.panels.js +1 -1
  135. package/static/widget/snag.runtime.js +2 -2
  136. package/static/widget/snag.text.js +1 -1
  137. package/vercel.json +4 -0
  138. package/static/dashboard/assets/index-DsUJ96yc.css +0 -1
  139. package/static/dashboard/assets/index-DultqpS7.js +0 -1
@@ -1 +0,0 @@
1
- (function(){const n=document.createElement("link").relList;if(n&&n.supports&&n.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))o(i);new MutationObserver(i=>{for(const s of i)if(s.type==="childList")for(const a of s.addedNodes)a.tagName==="LINK"&&a.rel==="modulepreload"&&o(a)}).observe(document,{childList:!0,subtree:!0});function r(i){const s={};return i.integrity&&(s.integrity=i.integrity),i.referrerPolicy&&(s.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?s.credentials="include":i.crossOrigin==="anonymous"?s.credentials="omit":s.credentials="same-origin",s}function o(i){if(i.ep)return;i.ep=!0;const s=r(i);fetch(i.href,s)}})();var ee,C,Pe,U,pe,xe,Ie,te,V,F,Ee,ae,ie,se,Q={},X=[],Be=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,ne=Array.isArray;function D(e,n){for(var r in n)e[r]=n[r];return e}function ce(e){e&&e.parentNode&&e.parentNode.removeChild(e)}function We(e,n,r){var o,i,s,a={};for(s in n)s=="key"?o=n[s]:s=="ref"?i=n[s]:a[s]=n[s];if(arguments.length>2&&(a.children=arguments.length>3?ee.call(arguments,2):r),typeof e=="function"&&e.defaultProps!=null)for(s in e.defaultProps)a[s]===void 0&&(a[s]=e.defaultProps[s]);return K(e,a,o,i,null)}function K(e,n,r,o,i){var s={type:e,props:n,key:r,ref:o,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:i??++Pe,__i:-1,__u:0};return i==null&&C.vnode!=null&&C.vnode(s),s}function N(e){return e.children}function J(e,n){this.props=e,this.context=n}function q(e,n){if(n==null)return e.__?q(e.__,e.__i+1):null;for(var r;n<e.__k.length;n++)if((r=e.__k[n])!=null&&r.__e!=null)return r.__e;return typeof e.type=="function"?q(e):null}function Ge(e){if(e.__P&&e.__d){var n=e.__v,r=n.__e,o=[],i=[],s=D({},n);s.__v=n.__v+1,C.vnode&&C.vnode(s),de(e.__P,s,n,e.__n,e.__P.namespaceURI,32&n.__u?[r]:null,o,r??q(n),!!(32&n.__u),i),s.__v=n.__v,s.__.__k[s.__i]=s,Le(o,s,i),n.__e=n.__=null,s.__e!=r&&je(s)}}function je(e){if((e=e.__)!=null&&e.__c!=null)return e.__e=e.__c.base=null,e.__k.some(function(n){if(n!=null&&n.__e!=null)return e.__e=e.__c.base=n.__e}),je(e)}function me(e){(!e.__d&&(e.__d=!0)&&U.push(e)&&!Z.__r++||pe!=C.debounceRendering)&&((pe=C.debounceRendering)||xe)(Z)}function Z(){try{for(var e,n=1;U.length;)U.length>n&&U.sort(Ie),e=U.shift(),n=U.length,Ge(e)}finally{U.length=Z.__r=0}}function Ne(e,n,r,o,i,s,a,c,_,d,p){var k,l,h,m,y,b,f=o&&o.__k||X,g=n.length;for(_=ze(r,n,f,_,g),k=0;k<g;k++)(h=r.__k[k])!=null&&(l=h.__i!=-1&&f[h.__i]||Q,h.__i=k,b=de(e,h,l,i,s,a,c,_,d,p),m=h.__e,h.ref&&l.ref!=h.ref&&(l.ref&&ue(l.ref,null,h),p.push(h.ref,h.__c||m,h)),y==null&&m!=null&&(y=m),4&h.__u?(_=Re(h,_,e),l.__e&&(l.__e=null)):typeof h.type=="function"&&b!==void 0?_=b:m&&(_=m.nextSibling),h.__u&=-7);return r.__e=y,_}function ze(e,n,r,o,i){var s,a,c,_,d,p=r.length,k=p,l=0;for(e.__k=new Array(i),s=0;s<i;s++)(a=n[s])!=null&&typeof a!="boolean"&&typeof a!="function"?(typeof a=="string"||typeof a=="number"||typeof a=="bigint"||a.constructor==String?a=e.__k[s]=K(null,a,null,null,null):ne(a)?a=e.__k[s]=K(N,{children:a},null,null,null):a.constructor===void 0&&a.__b>0?a=e.__k[s]=K(a.type,a.props,a.key,a.ref?a.ref:null,a.__v):e.__k[s]=a,_=s+l,a.__=e,a.__b=e.__b+1,c=null,(d=a.__i=Ve(a,r,_,k))!=-1&&(k--,(c=r[d])&&(c.__u|=2)),c==null||c.__v==null?(d==-1&&(i>p?l--:i<p&&l++),typeof a.type!="function"&&(a.__u|=4)):d!=_&&(d==_-1?l--:d==_+1?l++:(d>_?l--:l++,a.__u|=4))):e.__k[s]=null;if(k)for(s=0;s<p;s++)(c=r[s])!=null&&(2&c.__u)==0&&(c.__e==o&&(o=q(c)),qe(c,c));return o}function Re(e,n,r){var o,i;if(typeof e.type=="function"){for(o=e.__k,i=0;o&&i<o.length;i++)o[i]&&(o[i].__=e,n=Re(o[i],n,r));return n}e.__e!=n&&(n&&e.type&&!n.parentNode&&(n=q(e)),n=r.insertBefore(e.__e,n||null));do n=n&&n.nextSibling;while(n!=null&&n.nodeType==8);return n}function Ve(e,n,r,o){var i,s,a,c=e.key,_=e.type,d=n[r],p=d!=null&&(2&d.__u)==0;if(d===null&&c==null||p&&c==d.key&&_==d.type)return r;if(o>(p?1:0)){for(i=r-1,s=r+1;i>=0||s<n.length;)if((d=n[a=i>=0?i--:s++])!=null&&(2&d.__u)==0&&c==d.key&&_==d.type)return a}return-1}function fe(e,n,r){n[0]=="-"?e.setProperty(n,r??""):e[n]=r==null?"":typeof r!="number"||Be.test(n)?r:r+"px"}function G(e,n,r,o,i){var s,a;e:if(n=="style")if(typeof r=="string")e.style.cssText=r;else{if(typeof o=="string"&&(e.style.cssText=o=""),o)for(n in o)r&&n in r||fe(e.style,n,"");if(r)for(n in r)o&&r[n]==o[n]||fe(e.style,n,r[n])}else if(n[0]=="o"&&n[1]=="n")s=n!=(n=n.replace(Ee,"$1")),a=n.toLowerCase(),n=a in e||n=="onFocusOut"||n=="onFocusIn"?a.slice(2):n.slice(2),e.l||(e.l={}),e.l[n+s]=r,r?o?r[F]=o[F]:(r[F]=ae,e.addEventListener(n,s?se:ie,s)):e.removeEventListener(n,s?se:ie,s);else{if(i=="http://www.w3.org/2000/svg")n=n.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if(n!="width"&&n!="height"&&n!="href"&&n!="list"&&n!="form"&&n!="tabIndex"&&n!="download"&&n!="rowSpan"&&n!="colSpan"&&n!="role"&&n!="popover"&&n in e)try{e[n]=r??"";break e}catch{}typeof r=="function"||(r==null||r===!1&&n[4]!="-"?e.removeAttribute(n):e.setAttribute(n,n=="popover"&&r==1?"":r))}}function ve(e){return function(n){if(this.l){var r=this.l[n.type+e];if(n[V]==null)n[V]=ae++;else if(n[V]<r[F])return;return r(C.event?C.event(n):n)}}}function de(e,n,r,o,i,s,a,c,_,d){var p,k,l,h,m,y,b,f,g,T,R,v,u,S,A,$,j=n.type;if(n.constructor!==void 0)return null;128&r.__u&&(_=!!(32&r.__u),s=[c=n.__e=r.__e]),(p=C.__b)&&p(n);e:if(typeof j=="function"){k=a.length;try{if(g=n.props,T=j.prototype&&j.prototype.render,R=(p=j.contextType)&&o[p.__c],v=p?R?R.props.value:p.__:o,r.__c?f=(l=n.__c=r.__c).__=l.__E:(T?n.__c=l=new j(g,v):(n.__c=l=new J(g,v),l.constructor=j,l.render=Je),R&&R.sub(l),l.state||(l.state={}),l.__n=o,h=l.__d=!0,l.__h=[],l._sb=[]),T&&l.__s==null&&(l.__s=l.state),T&&j.getDerivedStateFromProps!=null&&(l.__s==l.state&&(l.__s=D({},l.__s)),D(l.__s,j.getDerivedStateFromProps(g,l.__s))),m=l.props,y=l.state,l.__v=n,h)T&&j.getDerivedStateFromProps==null&&l.componentWillMount!=null&&l.componentWillMount(),T&&l.componentDidMount!=null&&l.__h.push(l.componentDidMount);else{if(T&&j.getDerivedStateFromProps==null&&g!==m&&l.componentWillReceiveProps!=null&&l.componentWillReceiveProps(g,v),n.__v==r.__v||!l.__e&&l.shouldComponentUpdate!=null&&l.shouldComponentUpdate(g,l.__s,v)===!1){n.__v!=r.__v&&(l.props=g,l.state=l.__s,l.__d=!1),n.__e=r.__e,n.__k=r.__k,n.__k.some(function(O){O&&(O.__=n)}),X.push.apply(l.__h,l._sb),l._sb=[],l.__h.length&&a.push(l),c=q(r);break e}l.componentWillUpdate!=null&&l.componentWillUpdate(g,l.__s,v),T&&l.componentDidUpdate!=null&&l.__h.push(function(){l.componentDidUpdate(m,y,b)})}if(l.context=v,l.props=g,l.__P=e,l.__e=!1,u=C.__r,S=0,T)l.state=l.__s,l.__d=!1,u&&u(n),p=l.render(l.props,l.state,l.context),X.push.apply(l.__h,l._sb),l._sb=[];else do l.__d=!1,u&&u(n),p=l.render(l.props,l.state,l.context),l.state=l.__s;while(l.__d&&++S<25);l.state=l.__s,l.getChildContext!=null&&(o=D(D({},o),l.getChildContext())),T&&!h&&l.getSnapshotBeforeUpdate!=null&&(b=l.getSnapshotBeforeUpdate(m,y)),A=p!=null&&p.type===N&&p.key==null?Ue(p.props.children):p,c=Ne(e,ne(A)?A:[A],n,r,o,i,s,a,c,_,d),l.base=n.__e,n.__u&=-161,l.__h.length&&a.push(l),f&&(l.__E=l.__=null)}catch(O){if(a.length=k,n.__v=null,_||s!=null){if(O.then){for(n.__u|=_?160:128;c&&c.nodeType==8&&c.nextSibling;)c=c.nextSibling;s!=null&&(s[s.indexOf(c)]=null),n.__e=c}else if(s!=null)for($=s.length;$--;)ce(s[$])}else n.__e=r.__e;n.__k==null&&(n.__k=r.__k||[]),O.then||De(n),C.__e(O,n,r)}}else s==null&&n.__v==r.__v?(n.__k=r.__k,n.__e=r.__e):c=n.__e=Ke(r.__e,n,r,o,i,s,a,_,d);return(p=C.diffed)&&p(n),128&n.__u?void 0:c}function De(e){e&&(e.__c&&(e.__c.__e=!0),e.__k&&e.__k.some(De))}function Le(e,n,r){for(var o=0;o<r.length;o++)ue(r[o],r[++o],r[++o]);C.__c&&C.__c(n,e),e.some(function(i){try{e=i.__h,i.__h=[],e.some(function(s){s.call(i)})}catch(s){C.__e(s,i.__v)}})}function Ue(e){return typeof e!="object"||e==null||e.__b>0?e:ne(e)?e.map(Ue):e.constructor!==void 0?null:D({},e)}function Ke(e,n,r,o,i,s,a,c,_){var d,p,k,l,h,m,y,b=r.props||Q,f=n.props,g=n.type;if(g=="svg"?i="http://www.w3.org/2000/svg":g=="math"?i="http://www.w3.org/1998/Math/MathML":i||(i="http://www.w3.org/1999/xhtml"),s!=null){for(d=0;d<s.length;d++)if((h=s[d])&&"setAttribute"in h==!!g&&(g?h.localName==g:h.nodeType==3)){e=h,s[d]=null;break}}if(e==null){if(g==null)return document.createTextNode(f);e=document.createElementNS(i,g,f.is&&f),c&&(C.__m&&C.__m(n,s),c=!1),s=null}if(g==null)b===f||c&&e.data==f||(e.data=f);else{if(s=g=="textarea"&&f.defaultValue!=null?null:s&&ee.call(e.childNodes),!c&&s!=null)for(b={},d=0;d<e.attributes.length;d++)b[(h=e.attributes[d]).name]=h.value;for(d in b)h=b[d],d=="dangerouslySetInnerHTML"?k=h:d=="children"||d in f||d=="value"&&"defaultValue"in f||d=="checked"&&"defaultChecked"in f||G(e,d,null,h,i);for(d in f)h=f[d],d=="children"?l=h:d=="dangerouslySetInnerHTML"?p=h:d=="value"?m=h:d=="checked"?y=h:c&&typeof h!="function"||b[d]===h||G(e,d,h,b[d],i);if(p)c||k&&(p.__html==k.__html||p.__html==e.innerHTML)||(e.innerHTML=p.__html),n.__k=[];else if(k&&(e.innerHTML=""),Ne(n.type=="template"?e.content:e,ne(l)?l:[l],n,r,o,g=="foreignObject"?"http://www.w3.org/1999/xhtml":i,s,a,s?s[0]:r.__k&&q(r,0),c,_),s!=null)for(d=s.length;d--;)ce(s[d]);c&&g!="textarea"||(d="value",g=="progress"&&m==null?e.removeAttribute("value"):m!=null&&(m!==e[d]||g=="progress"&&!m||g=="option"&&m!=b[d])&&G(e,d,m,b[d],i),d="checked",y!=null&&y!=e[d]&&G(e,d,y,b[d],i))}return e}function ue(e,n,r){try{if(typeof e=="function"){var o=typeof e.__u=="function";o&&e.__u(),o&&n==null||(e.__u=e(n))}else e.current=n}catch(i){C.__e(i,r)}}function qe(e,n,r){var o,i;if(C.unmount&&C.unmount(e),(o=e.ref)&&(o.current&&o.current!=e.__e||ue(o,null,n)),(o=e.__c)!=null){if(o.componentWillUnmount)try{o.componentWillUnmount()}catch(s){C.__e(s,n)}o.base=o.__P=o.__n=null}if(o=e.__k)for(i=0;i<o.length;i++)o[i]&&qe(o[i],n,r||typeof e.type!="function");r||ce(e.__e),e.__c=e.__=e.__e=void 0}function Je(e,n,r){return this.constructor(e,r)}function Ye(e,n,r){var o,i,s,a;n==document&&(n=document.documentElement),C.__&&C.__(e,n),i=(o=!1)?null:n.__k,s=[],a=[],de(n,e=n.__k=We(N,null,[e]),i||Q,Q,n.namespaceURI,i?null:n.firstChild?ee.call(n.childNodes):null,s,i?i.__e:n.firstChild,o,a),Le(s,e,a),e.props.children=null}ee=X.slice,C={__e:function(e,n,r,o){for(var i,s,a;n=n.__;)if((i=n.__c)&&!i.__)try{if((s=i.constructor)&&s.getDerivedStateFromError!=null&&(i.setState(s.getDerivedStateFromError(e)),a=i.__d),i.componentDidCatch!=null&&(i.componentDidCatch(e,o||{}),a=i.__d),a)return i.__E=i}catch(c){e=c}throw e}},Pe=0,J.prototype.setState=function(e,n){var r;r=this.__s!=null&&this.__s!=this.state?this.__s:this.__s=D({},this.state),typeof e=="function"&&(e=e(D({},r),this.props)),e&&D(r,e),e!=null&&this.__v&&(n&&this._sb.push(n),me(this))},J.prototype.forceUpdate=function(e){this.__v&&(this.__e=!0,e&&this.__h.push(e),me(this))},J.prototype.render=N,U=[],xe=typeof Promise=="function"?Promise.prototype.then.bind(Promise.resolve()):setTimeout,Ie=function(e,n){return e.__v.__b-n.__v.__b},Z.__r=0,te=Math.random().toString(8),V="__d"+te,F="__a"+te,Ee=/(PointerCapture)$|Capture$/i,ae=0,ie=ve(!1),se=ve(!0);var Qe=0;function t(e,n,r,o,i,s){n||(n={});var a,c,_=n;if("ref"in _)for(c in _={},n)c=="ref"?a=n[c]:_[c]=n[c];var d={type:e,props:_,key:r,ref:a,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:--Qe,__i:-1,__u:0,__source:i,__self:s};if(typeof e=="function"&&(a=e.defaultProps))for(c in a)_[c]===void 0&&(_[c]=a[c]);return C.vnode&&C.vnode(d),d}var B,P,re,ge,W=0,Oe=[],x=C,ye=x.__b,be=x.__r,we=x.diffed,ke=x.__c,Se=x.unmount,Ce=x.__;function _e(e,n){x.__h&&x.__h(P,e,W||n),W=0;var r=P.__H||(P.__H={__:[],__h:[]});return e>=r.__.length&&r.__.push({}),r.__[e]}function w(e){return W=1,Xe(Fe,e)}function Xe(e,n,r){var o=_e(B++,2);if(o.t=e,!o.__c&&(o.__=[Fe(void 0,n),function(c){var _=o.__N?o.__N[0]:o.__[0],d=o.t(_,c);_!==d&&(o.__N=[d,o.__[1]],o.__c.setState({}))}],o.__c=P,!P.__f)){var i=function(c,_,d){if(!o.__c.__H)return!0;var p=!1,k=o.__c.props!==c;if(o.__c.__H.__.some(function(h){if(h.__N){p=!0;var m=h.__[0];h.__=h.__N,h.__N=void 0,m!==h.__[0]&&(k=!0)}}),s){var l=s.call(this,c,_,d);return p?l||k:l}return!p||k};P.__f=!0;var s=P.shouldComponentUpdate,a=P.componentWillUpdate;P.componentWillUpdate=function(c,_,d){if(this.__e){var p=s;s=void 0,i(c,_,d),s=p}a&&a.call(this,c,_,d)},P.shouldComponentUpdate=i}return o.__N||o.__}function M(e,n){var r=_e(B++,3);!x.__s&&Me(r.__H,n)&&(r.__=e,r.u=n,P.__H.__h.push(r))}function Ze(e){return W=5,he(function(){return{current:e}},[])}function he(e,n){var r=_e(B++,7);return Me(r.__H,n)&&(r.__=e(),r.__H=n,r.__h=e),r.__}function He(e,n){return W=8,he(function(){return e},n)}function en(){for(var e;e=Oe.shift();){var n=e.__H;if(e.__P&&n)try{n.__h.some(Y),n.__h.some(oe),n.__h=[]}catch(r){n.__h=[],x.__e(r,e.__v)}}}x.__b=function(e){P=null,ye&&ye(e)},x.__=function(e,n){e&&n.__k&&n.__k.__m&&(e.__m=n.__k.__m),Ce&&Ce(e,n)},x.__r=function(e){be&&be(e),B=0;var n=(P=e.__c).__H;n&&(re===P?(n.__h=[],P.__h=[],n.__.some(function(r){r.__N&&(r.__=r.__N),r.u=r.__N=void 0})):(n.__h.some(Y),n.__h.some(oe),n.__h=[],B=0)),re=P},x.diffed=function(e){we&&we(e);var n=e.__c;n&&n.__H&&(n.__H.__h.length&&(Oe.push(n)!==1&&ge===x.requestAnimationFrame||((ge=x.requestAnimationFrame)||nn)(en)),n.__H.__.some(function(r){r.u&&(r.__H=r.u,r.u=void 0)})),re=P=null},x.__c=function(e,n){n.some(function(r){try{r.__h.some(Y),r.__h=r.__h.filter(function(o){return!o.__||oe(o)})}catch(o){n.some(function(i){i.__h&&(i.__h=[])}),n=[],x.__e(o,r.__v)}}),ke&&ke(e,n)},x.unmount=function(e){Se&&Se(e);var n,r=e.__c;r&&r.__H&&(r.__H.__.some(function(o){try{Y(o)}catch(i){n=i}}),r.__H=void 0,n&&x.__e(n,r.__v))};var $e=typeof requestAnimationFrame=="function";function nn(e){var n,r=function(){clearTimeout(o),$e&&cancelAnimationFrame(n),setTimeout(e)},o=setTimeout(r,35);$e&&(n=requestAnimationFrame(r))}function Y(e){var n=P,r=e.__c;typeof r=="function"&&(e.__c=void 0,r()),P=n}function oe(e){var n=P;e.__c=e.__(),P=n}function Me(e,n){return!e||e.length!==n.length||n.some(function(r,o){return r!==e[o]})}function Fe(e,n){return typeof n=="function"?n(e):n}const tn={csrf:"snag_csrf"},rn=tn.csrf,sn={csrf:"x-snagset-csrf"};class L extends Error{status;code;constructor(n,r){super(r.message),this.status=n,this.code=r.code}}function on(){for(const e of document.cookie.split(";")){const n=e.indexOf("=");if(n>0&&e.slice(0,n).trim()===rn)return e.slice(n+1).trim()}return""}async function E(e,n,r){const o=await fetch(n,{method:e,credentials:"same-origin",headers:{...r===void 0?{}:{"content-type":"application/json"},...e==="GET"?{}:{[sn.csrf]:on()}},...r===void 0?{}:{body:JSON.stringify(r)}});if(o.status===204)return;const i=await o.json().catch(()=>null);if(!o.ok){const s=i?.error;throw new L(o.status,s??{code:"unknown",message:`Request failed (${o.status}).`})}return i}const I={me:()=>E("GET","/api/v1/me"),setup:e=>E("POST","/api/v1/setup",e),login:(e,n)=>E("POST","/auth/login",{email:e,password:n}),logout:()=>E("POST","/auth/logout"),threads:(e,n={})=>{const r=new URLSearchParams;n.status&&r.set("status",n.status),n.route&&r.set("route",n.route),n.round&&r.set("round",String(n.round)),n.q&&r.set("q",n.q),n.since&&r.set("since",n.since);const o=r.toString();return E("GET",`/api/v1/projects/${encodeURIComponent(e)}/threads${o?`?${o}`:""}`)},createProject:(e,n)=>E("POST","/api/v1/projects",{name:e,origins:n}),setAudience:(e,n)=>E("PATCH",`/api/v1/projects/${encodeURIComponent(e)}`,{writeMode:n}),origins:e=>E("GET",`/api/v1/projects/${encodeURIComponent(e)}/origins`),addOrigin:(e,n)=>E("POST",`/api/v1/projects/${encodeURIComponent(e)}/origins`,{origin:n}),rounds:e=>E("GET",`/api/v1/projects/${encodeURIComponent(e)}/rounds`),createRound:(e,n)=>E("POST",`/api/v1/projects/${encodeURIComponent(e)}/rounds`,{name:n}),setStatus:(e,n,r)=>E("PATCH",`/api/v1/projects/${encodeURIComponent(e)}/threads/${encodeURIComponent(n)}`,{status:r}),addComment:(e,n)=>E("POST",`/api/v1/threads/${encodeURIComponent(e)}/comments`,{id:crypto.randomUUID(),body:n}),listLinks:e=>E("GET",`/api/v1/projects/${encodeURIComponent(e)}/review-links`),mintLink:(e,n)=>E("POST",`/api/v1/projects/${encodeURIComponent(e)}/review-links`,n),revokeLink:e=>E("DELETE",`/api/v1/review-links/${encodeURIComponent(e)}`)};function Te(e){const n=new Date(e),r=Math.round((Date.now()-n.getTime())/6e4);return r<1?"just now":r<60?`${r}m ago`:r<1440?`${Math.round(r/60)}h ago`:n.toLocaleDateString(void 0,{day:"numeric",month:"short"})}function ln({context:e}){const n=e?.capture,r=e?.viewport,i=[["Viewport",r?.w?`${r.w} × ${r.h}`:null],["Browser",e?.browser??e?.ua??null],["Platform",e?.os??e?.platform??null],["Device pixel ratio",e?.dpr??null]].filter(([,c])=>c!=null&&c!==""),s=n?.category&&n.category!=="ok"&&n.category!=="full";return!i.length&&!n?null:t("section",{class:"block",children:[t("h2",{children:["Capture",t("button",{type:"button",class:"linkish",style:"float:right;font-size:12px",onClick:()=>{navigator.clipboard?.writeText(JSON.stringify(e,null,2))},children:"Copy environment"})]}),i.length>0&&t("dl",{class:"kv",children:i.map(([c,_])=>t(N,{children:[t("dt",{children:c}),t("dd",{children:String(_)})]}))}),s&&t("p",{class:"warn",style:"margin:10px 0 0",children:[t("b",{children:n.category}),n.reasons?.length?` — ${n.reasons.join("; ")}`:""]}),n?.blindSpots?.length?t("p",{class:"warn",style:"margin:6px 0 0",children:[n.blindSpots.length," blind spot",n.blindSpots.length===1?"":"s",": ",n.blindSpots.join("; ")]}):null,n?.droppedCategories?.length?t("p",{class:"warn",style:"margin:6px 0 0",children:["Dropped: ",n.droppedCategories.join(", ")]}):null]})}function an({onReply:e}){const[n,r]=w(""),[o,i]=w(!1),[s,a]=w("");return t("form",{class:"composer",onSubmit:async c=>{c.preventDefault();const _=n.trim();if(!(!_||o)){i(!0),a("");try{await e(_),r("")}catch(d){a(d instanceof L?d.message:"Could not send that reply.")}finally{i(!1)}}},children:[t("label",{class:"field",children:[t("span",{children:"Reply"}),t("textarea",{rows:3,placeholder:"Write a reply…",value:n,disabled:o,onInput:c=>r(c.target.value)})]}),s&&t("p",{class:"err",children:s}),t("button",{class:"btn btn-primary",type:"submit",disabled:o||!n.trim(),children:o?"Sending…":"Reply"})]})}function cn({thread:e,onStatus:n,onReply:r,busy:o}){const i=e.attachments?.find(c=>c.kind==="screenshot")??e.attachments?.[0],s=e.anchor?.label??"",a=e.anchor??{};return t("article",{class:"detail detail-open",children:[t("div",{class:"detail-head",children:[t("span",{class:"key",children:e.key}),t("h1",{children:s||"A comment on this page"}),t("span",{class:`status status-${e.status}`,children:le[e.status]??e.status})]}),t("p",{style:"margin:6px 0 0;color:var(--ink-soft);font-size:13px",children:["Round ",e.roundNumber," · ",e.route||"/"," · left by ",e.createdBy.name||"someone"," ",Te(e.createdAt)]}),i?t("figure",{class:"shot",children:[t("img",{src:i.url,alt:`Screenshot of the page when ${e.key} was left`,width:i.width,height:i.height,loading:"lazy"}),t("figcaption",{children:["captured at ",i.width??"?"," × ",i.height??"?"]})]}):t("div",{class:"no-shot",children:[t("b",{children:"No screenshot for this one."}),t("p",{style:"margin:6px 0 0",children:"Either this instance had no bucket connected when it was left, or the reviewer turned the picture off for this comment. The anchor and the page context below are unaffected."})]}),t("section",{class:"thread",children:[e.comments.length===0&&t("p",{style:"color:var(--ink-soft)",children:"This thread has no readable comments."}),e.comments.map(c=>t("div",{class:"comment",children:[t("div",{class:"comment-head",children:[t("b",{children:c.author.name||"Anonymous"}),c.author.kind==="agent"&&t("span",{class:"agent",children:"agent"}),t("span",{style:"color:var(--ink-faint)",children:Te(c.createdAt)})]}),t("p",{children:c.body??t("i",{style:"color:var(--ink-faint)",children:"deleted"})})]},c.id))]}),t(an,{onReply:r}),t("section",{class:"block",children:[t("h2",{children:"Anchor"}),t("dl",{class:"kv",children:[t("dt",{children:"State"}),t("dd",{children:e.anchorState}),s&&t(N,{children:[t("dt",{children:"Label"}),t("dd",{children:s})]}),a.css&&t(N,{children:[t("dt",{children:"Selector"}),t("dd",{children:String(a.css)})]}),a.domid&&t(N,{children:[t("dt",{children:"DOM id"}),t("dd",{children:String(a.domid)})]}),a.page?.pathname&&t(N,{children:[t("dt",{children:"Path"}),t("dd",{children:String(a.page.pathname)})]})]})]}),t(ln,{context:e.context??{}}),t("div",{class:"actions",children:[e.status!=="resolved"?t("button",{class:"btn btn-primary",disabled:o,onClick:()=>n("resolved"),children:"Mark resolved"}):t("button",{class:"btn",disabled:o,onClick:()=>n("open"),children:"Reopen"}),e.status!=="progress"&&e.status!=="resolved"&&t("button",{class:"btn",disabled:o,onClick:()=>n("progress"),children:"In progress"}),a.page?.origin&&t("a",{class:"btn",href:`${a.page.origin}${a.page.pathname??"/"}?snag_t=${encodeURIComponent(e.key)}`,target:"_blank",rel:"noreferrer noopener",children:"Open on site ↗"})]})]})}function z(e){return e?new Date(e).toLocaleDateString(void 0,{day:"numeric",month:"short",year:"numeric"}):"—"}function dn({uid:e,rounds:n}){const[r,o]=w(null),[i,s]=w(""),[a,c]=w(null),[_,d]=w(null),[p,k]=w(""),[l,h]=w("14"),[m,y]=w(""),[b,f]=w(!1),g=()=>{o(null),I.listLinks(e).then(v=>o(v.data)).catch(v=>s(v instanceof L?v.message:"Could not load the links."))};M(()=>{c(null),s(""),g()},[e]);const T=async v=>{v.preventDefault();const u=p.trim();if(!(!u||b)){f(!0),s("");try{const S=Number(l),A=Number.isFinite(S)&&S>0?new Date(Date.now()+S*864e5).toISOString():void 0,$=await I.mintLink(e,{name:u,...A?{expiresAt:A}:{},...m?{roundId:m}:{}});c($),k(""),h("14"),y(""),g()}catch(S){s(S instanceof L?S.message:"Could not create that link.")}finally{f(!1)}}},R=async v=>{if(confirm(`Revoke "${v.name}"? Every session minted from it is out within 10 s. This cannot be undone — minting a new link is the recovery.`)){d(v.id),s("");try{await I.revokeLink(v.id),c(u=>u?.id===v.id?null:u),g()}catch(u){s(u instanceof L?u.message:"Could not revoke that link.")}finally{d(null)}}};return t("div",{class:"links",children:[t("div",{class:"links-list",children:[t("h1",{class:"links-title",children:"Review links"}),i&&t("p",{class:"err",children:i}),r===null&&t("p",{class:"empty",children:"Loading…"}),r?.length===0&&t("div",{class:"empty",children:[t("h2",{children:"No links yet"}),t("p",{children:"Mint one on the right — once this project needs a link, it is the only way a reviewer gets in."})]}),r&&r.length>0&&t("table",{class:"link-table",children:[t("thead",{children:t("tr",{children:[t("th",{children:"Name"}),t("th",{children:"Created"}),t("th",{children:"Expires"}),t("th",{children:"Last used"}),t("th",{children:"Uses"}),t("th",{})]})}),t("tbody",{children:r.map(v=>{const u=!!v.revokedAt,S=!u&&new Date(v.expiresAt).getTime()<=Date.now(),A=v.roundId?n?.find($=>$.id===v.roundId):null;return t("tr",{class:u||S?"link-dead":"",children:[t("td",{children:[v.name,A&&t("span",{class:"link-round",children:A.name})]}),t("td",{children:z(v.createdAt)}),t("td",{children:u?t("span",{class:"warn",children:["revoked ",z(v.revokedAt)]}):S?t("span",{class:"warn",children:"expired"}):z(v.expiresAt)}),t("td",{children:z(v.lastUsedAt)}),t("td",{children:v.useCount}),t("td",{children:!u&&t("button",{class:"btn",disabled:_===v.id,onClick:()=>void R(v),children:_===v.id?"Revoking…":"Revoke"})})]},v.id)})})]})]}),t("div",{class:"links-side",children:[a&&t("div",{class:"card minted",children:[t("h2",{children:['"',a.name,'" is ready']}),t("p",{class:"sub",children:["This is the only time the token is shown — the list on the left never carries it again. Paste it after the reviewed site's URL, e.g. ",t("code",{children:["https://yoursite.com/page",a.fragment]}),"."]}),t("div",{class:"token-box",children:[t("code",{children:a.fragment}),t("button",{class:"btn",onClick:()=>void navigator.clipboard.writeText(a.fragment).catch(()=>{}),children:"Copy"})]}),t("button",{class:"linkish",style:"margin-top:10px",onClick:()=>c(null),children:"Done"})]}),t("form",{class:"card",onSubmit:T,children:[t("h2",{children:"New link"}),t("label",{class:"field",children:[t("span",{children:"Name"}),t("input",{required:!0,placeholder:"Client review — round 2",value:p,onInput:v=>k(v.target.value)})]}),t("label",{class:"field",children:[t("span",{children:"Expires in (days, up to 90)"}),t("input",{type:"number",min:1,max:90,value:l,onInput:v=>h(v.target.value)})]}),n&&n.length>0&&t("label",{class:"field",children:[t("span",{children:"Pin to a round (optional)"}),t("select",{value:m,onChange:v=>y(v.target.value),children:[t("option",{value:"",children:"Any round"}),n.map(v=>t("option",{value:v.id,children:v.name},v.id))]})]}),t("button",{class:"btn btn-primary",type:"submit",disabled:b||!p.trim(),children:b?"Creating…":"Create link"})]})]})]})}function un({me:e,onAdded:n,origin:r}){const[o,i]=w(""),[s,a]=w(""),[c,_]=w(!1),[d,p]=w(""),[k,l]=w(null);return t("div",{class:"sites",children:[t("section",{class:"site-add",children:[t("h2",{children:"Add a site"}),t("form",{onSubmit:async m=>{if(m.preventDefault(),!c){_(!0),p("");try{const y=await I.createProject(o.trim(),s.trim());l({uid:y.uid,name:y.name,...y.warning?{warning:y.warning}:{}}),i(""),a(""),n(y.uid)}catch(y){p(y instanceof L?y.message:"Something went wrong. Try again.")}finally{_(!1)}}},children:[t("label",{children:["Name",t("input",{value:o,placeholder:"Acme redesign",onInput:m=>i(m.target.value),required:!0})]}),t("label",{children:["Where it runs",t("input",{value:s,placeholder:"https://staging.acme.com, http://localhost:3000",onInput:m=>a(m.target.value)}),t("small",{children:["Comma-separated, with the scheme. Only these can talk to the site — a tag on any other address is ignored. ",t("code",{children:"https://*.acme.com"})," covers subdomains."]})]}),t("button",{type:"submit",disabled:c||!o.trim(),children:c?"Adding…":"Add site"}),d&&t("p",{class:"error",children:d})]})]}),k&&t(_n,{site:k,origin:r}),t("section",{class:"site-list",children:[t("h2",{children:"Your sites"}),t("ul",{children:e.projects.map(m=>t("li",{children:[t("strong",{children:m.name}),t("code",{children:m.uid}),t("span",{children:[m.threads," snag",m.threads===1?"":"s"," · ",m.unresolved," open"]})]},m.uid))})]})]})}function _n({site:e,origin:n}){const[r,o]=w([]),[i,s]=w(""),[a,c]=w(""),[_,d]=w("everyone"),[p,k]=w(""),l=y=>{const b=_;d(y),k(""),I.setAudience(e.uid,y==="everyone"?"open":"link-required").catch(()=>{d(b),k("Could not save — try again.")})},h=He(()=>{I.origins(e.uid).then(y=>o(y.origins)).catch(()=>o([]))},[e.uid]);M(h,[h]);const m=`<script src="${n}/snag.js" data-snag-site="${e.uid}" defer><\/script>`;return t("section",{class:"site-made",children:[t("h2",{children:[e.name," is ready"]}),t("p",{children:"Paste this into the site, immediately before the closing </body> tag."}),t("div",{class:"site-audience",role:"radiogroup","aria-label":"Who sees the toolbar",children:[t("label",{children:[t("input",{type:"radio",name:"audience",checked:_==="everyone",onChange:()=>l("everyone")}),t("span",{children:[t("strong",{children:"Everyone on these addresses"})," — the toolbar just appears, and anyone can comment. For staging. Saved to the server: change it here any time, no re-paste."]})]}),t("label",{children:[t("input",{type:"radio",name:"audience",checked:_==="links",onChange:()=>l("links")}),t("span",{children:[t("strong",{children:"Only people with a review link"})," — visitors see nothing. For production, where the visitors are your client's customers."]})]}),p&&t("p",{class:"error",children:p})]}),t("pre",{children:t("code",{children:m})}),t("button",{class:"linkish",onClick:()=>{navigator.clipboard?.writeText(m)},children:"Copy"}),t("h3",{children:"Allowed origins"}),r.length?t("ul",{class:"origins",children:r.map(y=>t("li",{children:t("code",{children:y})},y))}):t("p",{class:"warn",children:e.warning??"None yet — the tag will load and every request from it will be refused. Add one below."}),t("form",{onSubmit:async y=>{y.preventDefault();const b=i.trim();if(b){c("");try{const f=await I.addOrigin(e.uid,b);o(f.origins),s("")}catch(f){c(f instanceof L?f.message:"Could not add that origin.")}}},children:[t("input",{value:i,placeholder:"https://www.acme.com",onInput:y=>s(y.target.value)}),t("button",{type:"submit",disabled:!i.trim(),children:"Allow"}),a&&t("p",{class:"error",children:a})]})]})}function hn(e,n,r=[]){const o=new Set(r),i=e.filter(s=>!o.has(s.id));for(const s of n){if(o.has(s.id))continue;const a=i.findIndex(c=>c.id===s.id);a===-1?i.push(s):i[a]=s}return i}function pn({token:e,onClaimed:n}){const[r,o]=w(""),[i,s]=w(""),[a,c]=w(""),[_,d]=w(""),[p,k]=w(!1),[l,h]=w(""),[m,y]=w(null);return m?t(mn,{site:m,onContinue:n}):t("div",{class:"setup",children:[t("h1",{children:"Set up Snagset"}),t("p",{class:"setup-lede",children:"This instance has not been claimed yet. The account you make here is the only one, until you add another."}),t("form",{onSubmit:async f=>{if(f.preventDefault(),!p){k(!0),h("");try{const g=await I.setup({token:e,orgName:r.trim()||"My studio",projectName:i.trim(),email:a.trim(),password:_});y(g.project)}catch(g){h(g instanceof L?g.message:"Something went wrong. Try again.")}finally{k(!1)}}},children:[t("label",{children:["Your email",t("input",{type:"email",value:a,autocomplete:"username",required:!0,onInput:f=>c(f.target.value)})]}),t("label",{children:["Password",t("input",{type:"password",value:_,autocomplete:"new-password",required:!0,minLength:12,onInput:f=>d(f.target.value)}),t("small",{children:"At least 12 characters. There is no reset email on a fresh install — keep it."})]}),t("label",{children:["Studio name ",t("span",{class:"setup-opt",children:"optional"}),t("input",{value:r,placeholder:"My studio",onInput:f=>o(f.target.value)})]}),t("label",{children:["First site ",t("span",{class:"setup-opt",children:"optional"}),t("input",{value:i,placeholder:"Acme redesign",onInput:f=>s(f.target.value)})]}),t("button",{type:"submit",disabled:p||!a.trim()||_.length<12,children:p?"Setting up…":"Create my account"}),l&&t("p",{class:"error",children:l})]})]})}function mn({site:e,onContinue:n}){const r=`<script src="${location.origin}/snag.js" data-snag-site="${e.uid}" defer><\/script>`;return t("div",{class:"setup",children:[t("h1",{children:[e.name," is ready"]}),t("p",{class:"setup-lede",children:"Paste this into the site you want reviewed, before the closing </body> tag."}),t("pre",{children:t("code",{children:r})}),t("div",{class:"setup-actions",children:[t("button",{type:"button",class:"linkish",onClick:()=>void navigator.clipboard?.writeText(r),children:"Copy"}),t("button",{type:"button",onClick:n,children:"Open the dashboard"})]}),t("p",{class:"setup-note",children:"The site's address has to be on its allow-list before comments can reach you — add it on the Sites screen. A tag on any other address loads and is ignored."})]})}const fn=["open","progress","review","resolved"],le={open:"Active",progress:"In progress",review:"In review",resolved:"Resolved"};function H(){const e=new URLSearchParams(location.search);return{project:e.get("project")??"",thread:e.get("t")??"",status:e.get("status")??"",q:e.get("q")??"",round:e.get("round")??"",screen:e.get("screen")??"",claim:e.get("claim")??""}}function Ae(e){const n={...H(),...e},r=new URLSearchParams;n.project&&r.set("project",n.project),n.thread&&r.set("t",n.thread),n.status&&r.set("status",n.status),n.q&&r.set("q",n.q),n.round&&r.set("round",n.round),n.screen&&r.set("screen",n.screen);const o=`${location.pathname}${r.toString()?`?${r}`:""}`;history.pushState(null,"",o)}function vn({onIn:e}){const[n,r]=w(""),[o,i]=w(""),[s,a]=w(""),[c,_]=w(!1);return t("div",{class:"gate",children:t("form",{class:"card",onSubmit:async d=>{d.preventDefault(),_(!0),a("");try{await I.login(n,o),e()}catch(p){a(p instanceof L?p.message:"Could not reach the server.")}finally{_(!1)}},children:[t("h1",{children:"Sign in"}),t("p",{class:"sub",children:"The studio side of Snagset. Reviewers do not sign in — they open a link."}),s&&t("p",{class:"err",children:s}),t("label",{class:"field",children:[t("span",{children:"Email"}),t("input",{type:"email",autocomplete:"username",required:!0,value:n,onInput:d=>r(d.target.value)})]}),t("label",{class:"field",children:[t("span",{children:"Password"}),t("input",{type:"password",autocomplete:"current-password",required:!0,value:o,onInput:d=>i(d.target.value)})]}),t("button",{class:"btn btn-primary",disabled:c,children:c?"Signing in…":"Sign in"}),t("p",{class:"sub",style:"margin:14px 0 0",children:["Forgotten it? There is no reset email on a fresh install — set a new one from the machine that runs the server: ",t("code",{children:"snagset passwd you@example.com"})]})]})})}function gn(){const[e,n]=w(null),[r,o]=w("loading"),[i,s]=w(H()),[a,c]=w(null),_=Ze(null),[d,p]=w(!1),[k,l]=w(null),[h,m]=w(null),y=He(async()=>{try{const u=await I.me();n(u),o("in"),!H().project&&u.projects[0]&&(Ae({project:u.projects[0].uid}),s(H()))}catch{o("out")}},[]);M(()=>{y(),fetch("/api/v1/meta").then(S=>S.json()).then(l).catch(()=>{});const u=()=>s(H());return addEventListener("popstate",u),()=>removeEventListener("popstate",u)},[y]);const b=i.project;M(()=>{if(r!=="in"||!b)return;let u=!0;return m(null),I.rounds(b).then(S=>u&&m(S.data)).catch(()=>u&&m([])),()=>{u=!1}},[r,b]);const f=i.round?Number(i.round):h?.[0]?.number??null;M(()=>{if(r!=="in"||!b||f===null)return;let u=!0;return c(null),I.threads(b,{round:f,...i.status?{status:i.status}:{},...i.q?{q:i.q}:{}}).then(S=>{u&&(c(S.data),_.current=S.serverTime)}).catch(()=>u&&c([])),()=>{u=!1}},[r,b,f,i.status,i.q]),M(()=>{if(r!=="in"||!b)return;let u=0;const S=()=>{if(document.hidden||!_.current)return;const A=Date.now();A-u<3e4||(u=A,I.threads(b,{...f===null?{}:{round:f},since:_.current,...i.status?{status:i.status}:{},...i.q?{q:i.q}:{}}).then($=>{_.current=$.serverTime,!(!$.data.length&&!$.deleted?.length)&&c(j=>j&&hn(j,$.data,$.deleted))}).catch(()=>{}))};return document.addEventListener("visibilitychange",S),()=>document.removeEventListener("visibilitychange",S)},[r,b,f,i.status,i.q]);const g=he(()=>a?.find(u=>u.key===i.thread)??null,[a,i.thread]),T=u=>{Ae(u),s(H())};if(r==="loading")return t("div",{class:"empty",children:"Loading…"});if(r==="out"&&i.claim)return t(pn,{token:i.claim,onClaimed:()=>void y()});if(r==="out")return t(vn,{onIn:()=>void y()});const R=async u=>{if(g){p(!0);try{const S=await I.setStatus(b,g.id,u);c(A=>A?.map($=>$.id===S.id?{...$,...S}:$)??A)}finally{p(!1)}}},v=async u=>{if(!g)return;const S=await I.addComment(g.id,u);c(A=>A?.map($=>$.id===g.id?{...$,comments:[...$.comments,S],commentCount:$.commentCount+1}:$)??A)};return t("div",{class:"shell",children:[t("header",{class:"topbar",children:[t("div",{class:"brand",children:["Snagset ",t("span",{children:"studio"})]}),t("select",{value:b,onChange:u=>T({project:u.target.value,thread:""}),children:e.projects.map(u=>t("option",{value:u.uid,children:[u.name," · ",u.unresolved," open"]},u.uid))}),h&&h.length>0&&t("select",{value:String(f??""),onChange:u=>T({round:u.target.value,thread:""}),children:h.map(u=>t("option",{value:String(u.number),children:[u.name,u.closed?" (closed)":""," · ",u.unresolved," open"]},u.id))}),t("button",{class:"linkish",title:"Start a new round. The page goes clean; nothing is deleted.",onClick:async()=>{const u=(h?.[0]?.number??0)+1,S=prompt("Name for the new round",`Round ${u}`);if(S===null)return;const A=await I.createRound(b,S).catch(()=>null);if(!A)return;const $=await I.rounds(b).catch(()=>null);$&&m($.data),T({round:String(A.number),thread:""})},children:"+ Round"}),t("button",{class:"linkish","aria-pressed":i.screen==="links",onClick:()=>T({screen:i.screen==="links"?"":"links",thread:""}),children:"Links"}),t("button",{class:"linkish","aria-pressed":i.screen==="sites",onClick:()=>T({screen:i.screen==="sites"?"":"sites",thread:""}),children:"Sites"}),t("div",{class:"spacer"}),t("span",{class:"who",children:e.user.email}),t("button",{class:"linkish",onClick:async()=>{await I.logout().catch(()=>{}),o("out")},children:"Sign out"})]}),i.screen==="sites"?t(un,{me:e,origin:location.origin,onAdded:async u=>{const S=await I.me().catch(()=>null);S&&n(S),T({project:u,thread:""})}}):i.screen==="links"?t(dn,{uid:b,rounds:h}):t(N,{children:[h&&f!==null&&t(N,{children:h.filter(u=>u.number!==f&&u.unresolved>0).map(u=>t("button",{class:"carryover",onClick:()=>T({round:String(u.number),thread:""}),children:[t("b",{children:[u.unresolved," unresolved"]})," in ",u.name," — still open, not carried over. Go there ↗"]},u.id))}),t("div",{class:"inbox",children:[t("div",{class:"list",children:[t("div",{class:"filters",children:[t("input",{type:"search",placeholder:"Search comments",value:i.q,onInput:u=>T({q:u.target.value})}),fn.map(u=>t("button",{class:"chip","aria-pressed":i.status===u,onClick:()=>T({status:i.status===u?"":u}),children:le[u]},u))]}),t("div",{class:"rows",children:[a===null&&t("p",{class:"empty",children:"Loading…"}),a?.length===0&&t("div",{class:"empty",children:[t("h2",{children:"Nothing here"}),t("p",{children:i.q||i.status?"No comment matches that filter.":"No comments on this project yet. Paste the script tag on the site and click something."})]}),a?.map(u=>t("button",{class:"row","aria-current":u.key===i.thread,onClick:()=>T({thread:u.key}),children:[t("div",{class:"row-top",children:[t("span",{class:"key",children:u.key}),t("span",{class:`status status-${u.status}`,children:le[u.status]})]}),t("p",{class:"row-body",children:u.comments[0]?.body??u.anchor?.label??"(no comment)"}),t("div",{class:"row-meta",children:[t("span",{children:u.route||"/"}),t("span",{children:"·"}),t("span",{children:u.createdBy.name||"someone"}),u.attachments?.length?t("span",{children:"· 📷"}):null]})]},u.id))]})]}),g?t(cn,{thread:g,onStatus:u=>void R(u),onReply:v,busy:d}):t("div",{class:"empty",children:[t("h2",{children:"Pick a comment"}),t("p",{children:"Its screenshot, the thread, the anchor and the page context all open here."})]})]})]}),t("footer",{class:"foot",children:[t("span",{children:[e.org.name," · ",k?.version??"…"]}),k?.commit&&t("span",{children:k.commit.slice(0,8)})]})]})}Ye(t(gn,{}),document.getElementById("app"));