diff --git a/crates/librqbit/src/api_error.rs b/crates/librqbit/src/api_error.rs index fe2a2c2..3d787db 100644 --- a/crates/librqbit/src/api_error.rs +++ b/crates/librqbit/src/api_error.rs @@ -11,6 +11,14 @@ pub struct ApiError { } impl ApiError { + pub fn new_from_string(status: StatusCode, text: String) -> Self { + Self { + status: Some(status), + kind: ApiErrorKind::Other(anyhow::anyhow!("{}", text)), + plaintext: false, + } + } + pub const fn torrent_not_found(torrent_id: usize) -> Self { Self { status: Some(StatusCode::NOT_FOUND), diff --git a/crates/librqbit/src/session.rs b/crates/librqbit/src/session.rs index 381dcad..c32e465 100644 --- a/crates/librqbit/src/session.rs +++ b/crates/librqbit/src/session.rs @@ -185,10 +185,13 @@ fn compute_only_files>( #[serde_as] #[derive(Default, Clone, Serialize, Deserialize)] pub struct AddTorrentOptions { + #[serde(default)] pub paused: bool, pub only_files_regex: Option, pub only_files: Option>, + #[serde(default)] pub overwrite: bool, + #[serde(default)] pub list_only: bool, pub output_folder: Option, pub sub_folder: Option, diff --git a/crates/librqbit/webui/dist/assets/index.js b/crates/librqbit/webui/dist/assets/index.js index 4017f9a..f2249d0 100644 --- a/crates/librqbit/webui/dist/assets/index.js +++ b/crates/librqbit/webui/dist/assets/index.js @@ -41,4 +41,4 @@ Error generating stack: `+o.message+` Copyright (c) 2018 Jed Watson. Licensed under the MIT License (MIT), see http://jedwatson.github.io/classnames -*/(function(e){(function(){var t={}.hasOwnProperty;function n(){for(var r=[],l=0;l=0)&&(n[l]=e[l]);return n}function ia(e){return"default"+e.charAt(0).toUpperCase()+e.substr(1)}function mh(e){var t=hh(e,"string");return typeof t=="symbol"?t:String(t)}function hh(e,t){if(typeof e!="object"||e===null)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||"default");if(typeof r!="object")return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return(t==="string"?String:Number)(e)}function vh(e,t,n){var r=y.useRef(e!==void 0),l=y.useState(t),o=l[0],i=l[1],u=e!==void 0,s=r.current;return r.current=u,!u&&s&&o!==t&&i(t),[u?e:o,y.useCallback(function(a){for(var h=arguments.length,p=new Array(h>1?h-1:0),d=1;d{o.target===e&&(l(),t(o))},n+r)}function Uh(e){e.offsetHeight}const aa=e=>!e||typeof e=="function"?e:t=>{e.current=t};function Bh(e,t){const n=aa(e),r=aa(t);return l=>{n&&n(l),r&&r(l)}}function mo(e,t){return y.useMemo(()=>Bh(e,t),[e,t])}function Hh(e){return e&&"setState"in e?Nn.findDOMNode(e):e??null}const Wh=Wt.forwardRef(({onEnter:e,onEntering:t,onEntered:n,onExit:r,onExiting:l,onExited:o,addEndListener:i,children:u,childRef:s,...a},h)=>{const p=y.useRef(null),d=mo(p,s),S=T=>{d(Hh(T))},g=T=>N=>{T&&p.current&&T(p.current,N)},x=y.useCallback(g(e),[e]),R=y.useCallback(g(t),[t]),m=y.useCallback(g(n),[n]),c=y.useCallback(g(r),[r]),v=y.useCallback(g(l),[l]),w=y.useCallback(g(o),[o]),E=y.useCallback(g(i),[i]);return f.jsx(zh,{ref:h,...a,onEnter:x,onEntered:m,onEntering:R,onExit:c,onExited:w,onExiting:v,addEndListener:E,nodeRef:p,children:typeof u=="function"?(T,N)=>u(T,{...N,ref:S}):Wt.cloneElement(u,{ref:S})})}),Vh=Wh;function Qh(e){const t=y.useRef(e);return y.useEffect(()=>{t.current=e},[e]),t}function Fe(e){const t=Qh(e);return y.useCallback(function(...n){return t.current&&t.current(...n)},[t])}const Qf=e=>y.forwardRef((t,n)=>f.jsx("div",{...t,ref:n,className:M(t.className,e)})),Kf=Qf("h4");Kf.displayName="DivStyledAsH4";const Gf=y.forwardRef(({className:e,bsPrefix:t,as:n=Kf,...r},l)=>(t=H(t,"alert-heading"),f.jsx(n,{ref:l,className:M(e,t),...r})));Gf.displayName="AlertHeading";const Kh=Gf;function Gh(){return y.useState(null)}function Yh(){const e=y.useRef(!0),t=y.useRef(()=>e.current);return y.useEffect(()=>(e.current=!0,()=>{e.current=!1}),[]),t.current}function Xh(e){const t=y.useRef(null);return y.useEffect(()=>{t.current=e}),t.current}const Zh=typeof global<"u"&&global.navigator&&global.navigator.product==="ReactNative",Jh=typeof document<"u",ca=Jh||Zh?y.useLayoutEffect:y.useEffect,qh=["as","disabled"];function bh(e,t){if(e==null)return{};var n={},r=Object.keys(e),l,o;for(o=0;o=0)&&(n[l]=e[l]);return n}function ev(e){return!e||e.trim()==="#"}function Hu({tagName:e,disabled:t,href:n,target:r,rel:l,role:o,onClick:i,tabIndex:u=0,type:s}){e||(n!=null||r!=null||l!=null?e="a":e="button");const a={tagName:e};if(e==="button")return[{type:s||"button",disabled:t},a];const h=d=>{if((t||e==="a"&&ev(n))&&d.preventDefault(),t){d.stopPropagation();return}i==null||i(d)},p=d=>{d.key===" "&&(d.preventDefault(),h(d))};return e==="a"&&(n||(n="#"),t&&(n=void 0)),[{role:o??"button",disabled:void 0,tabIndex:t?void 0:u,href:n,target:e==="a"?r:void 0,"aria-disabled":t||void 0,rel:e==="a"?l:void 0,onClick:h,onKeyDown:p},a]}const tv=y.forwardRef((e,t)=>{let{as:n,disabled:r}=e,l=bh(e,qh);const[o,{tagName:i}]=Hu(Object.assign({tagName:n,disabled:r},l));return f.jsx(i,Object.assign({},l,o,{ref:t}))});tv.displayName="Button";const nv=["onKeyDown"];function rv(e,t){if(e==null)return{};var n={},r=Object.keys(e),l,o;for(o=0;o=0)&&(n[l]=e[l]);return n}function lv(e){return!e||e.trim()==="#"}const Yf=y.forwardRef((e,t)=>{let{onKeyDown:n}=e,r=rv(e,nv);const[l]=Hu(Object.assign({tagName:"a"},r)),o=Fe(i=>{l.onKeyDown(i),n==null||n(i)});return lv(r.href)||r.role==="button"?f.jsx("a",Object.assign({ref:t},r,l,{onKeyDown:o})):f.jsx("a",Object.assign({ref:t},r,{onKeyDown:n}))});Yf.displayName="Anchor";const ov=Yf,Xf=y.forwardRef(({className:e,bsPrefix:t,as:n=ov,...r},l)=>(t=H(t,"alert-link"),f.jsx(n,{ref:l,className:M(e,t),...r})));Xf.displayName="AlertLink";const iv=Xf,uv={[St]:"show",[Ht]:"show"},Zf=y.forwardRef(({className:e,children:t,transitionClasses:n={},onEnter:r,...l},o)=>{const i={in:!1,timeout:300,mountOnEnter:!1,unmountOnExit:!1,appear:!1,...l},u=y.useCallback((s,a)=>{Uh(s),r==null||r(s,a)},[r]);return f.jsx(Vh,{ref:o,addEndListener:Ah,...i,onEnter:u,childRef:t.ref,children:(s,a)=>y.cloneElement(t,{...a,className:M("fade",e,t.props.className,uv[s],n[s])})})});Zf.displayName="Fade";const Kl=Zf,sv={"aria-label":it.string,onClick:it.func,variant:it.oneOf(["white"])},Wu=y.forwardRef(({className:e,variant:t,"aria-label":n="Close",...r},l)=>f.jsx("button",{ref:l,type:"button",className:M("btn-close",t&&`btn-close-${t}`,e),"aria-label":n,...r}));Wu.displayName="CloseButton";Wu.propTypes=sv;const Jf=Wu,qf=y.forwardRef((e,t)=>{const{bsPrefix:n,show:r=!0,closeLabel:l="Close alert",closeVariant:o,className:i,children:u,variant:s="primary",onClose:a,dismissible:h,transition:p=Kl,...d}=yh(e,{show:"onClose"}),S=H(n,"alert"),g=Fe(m=>{a&&a(!1,m)}),x=p===!0?Kl:p,R=f.jsxs("div",{role:"alert",...x?void 0:d,ref:t,className:M(i,S,s&&`${S}-${s}`,h&&`${S}-dismissible`),children:[h&&f.jsx(Jf,{onClick:g,"aria-label":l,variant:o}),u]});return x?f.jsx(x,{unmountOnExit:!0,...d,ref:void 0,in:r,children:R}):r?R:null});qf.displayName="Alert";const fa=Object.assign(qf,{Link:iv,Heading:Kh}),bf=y.forwardRef(({as:e,bsPrefix:t,variant:n="primary",size:r,active:l=!1,disabled:o=!1,className:i,...u},s)=>{const a=H(t,"btn"),[h,{tagName:p}]=Hu({tagName:e,disabled:o,...u}),d=p;return f.jsx(d,{...h,...u,ref:s,disabled:o,className:M(i,a,l&&"active",n&&`${a}-${n}`,r&&`${a}-${r}`,u.href&&o&&"disabled")})});bf.displayName="Button";const tn=bf;function av(e){const t=y.useRef(e);return t.current=e,t}function ed(e){const t=av(e);y.useEffect(()=>()=>t.current(),[])}function cv(e,t){let n=0;return y.Children.map(e,r=>y.isValidElement(r)?t(r,n++):r)}function fv(e,t){return y.Children.toArray(e).some(n=>y.isValidElement(n)&&n.type===t)}function dv({as:e,bsPrefix:t,className:n,...r}){t=H(t,"col");const l=Df(),o=If(),i=[],u=[];return l.forEach(s=>{const a=r[s];delete r[s];let h,p,d;typeof a=="object"&&a!=null?{span:h,offset:p,order:d}=a:h=a;const S=s!==o?`-${s}`:"";h&&i.push(h===!0?`${t}${S}`:`${t}${S}-${h}`),d!=null&&u.push(`order${S}-${d}`),p!=null&&u.push(`offset${S}-${p}`)}),[{...r,className:M(n,...i,...u)},{as:e,bsPrefix:t,spans:i}]}const td=y.forwardRef((e,t)=>{const[{className:n,...r},{as:l="div",bsPrefix:o,spans:i}]=dv(e);return f.jsx(l,{...r,ref:t,className:M(n,!i.length&&o)})});td.displayName="Col";const Vu=td,nd=y.forwardRef(({bsPrefix:e,fluid:t=!1,as:n="div",className:r,...l},o)=>{const i=H(e,"container"),u=typeof t=="string"?`-${t}`:"-fluid";return f.jsx(n,{ref:o,...l,className:M(r,t?`${i}${u}`:i)})});nd.displayName="Container";const pv=nd;var mv=Function.prototype.bind.call(Function.prototype.call,[].slice);function dn(e,t){return mv(e.querySelectorAll(t))}function da(e,t){if(e.contains)return e.contains(t);if(e.compareDocumentPosition)return e===t||!!(e.compareDocumentPosition(t)&16)}const hv="data-rr-ui-";function vv(e){return`${hv}${e}`}const rd=y.createContext(Vn?window:void 0);rd.Provider;function Qu(){return y.useContext(rd)}const yv={type:it.string,tooltip:it.bool,as:it.elementType},Ku=y.forwardRef(({as:e="div",className:t,type:n="valid",tooltip:r=!1,...l},o)=>f.jsx(e,{...l,ref:o,className:M(t,`${n}-${r?"tooltip":"feedback"}`)}));Ku.displayName="Feedback";Ku.propTypes=yv;const ld=Ku,gv=y.createContext({}),ft=gv,od=y.forwardRef(({id:e,bsPrefix:t,className:n,type:r="checkbox",isValid:l=!1,isInvalid:o=!1,as:i="input",...u},s)=>{const{controlId:a}=y.useContext(ft);return t=H(t,"form-check-input"),f.jsx(i,{...u,ref:s,type:r,id:e||a,className:M(n,t,l&&"is-valid",o&&"is-invalid")})});od.displayName="FormCheckInput";const id=od,ud=y.forwardRef(({bsPrefix:e,className:t,htmlFor:n,...r},l)=>{const{controlId:o}=y.useContext(ft);return e=H(e,"form-check-label"),f.jsx("label",{...r,ref:l,htmlFor:n||o,className:M(t,e)})});ud.displayName="FormCheckLabel";const Gi=ud,sd=y.forwardRef(({id:e,bsPrefix:t,bsSwitchPrefix:n,inline:r=!1,reverse:l=!1,disabled:o=!1,isValid:i=!1,isInvalid:u=!1,feedbackTooltip:s=!1,feedback:a,feedbackType:h,className:p,style:d,title:S="",type:g="checkbox",label:x,children:R,as:m="input",...c},v)=>{t=H(t,"form-check"),n=H(n,"form-switch");const{controlId:w}=y.useContext(ft),E=y.useMemo(()=>({controlId:e||w}),[w,e]),T=!R&&x!=null&&x!==!1||fv(R,Gi),N=f.jsx(id,{...c,type:g==="switch"?"checkbox":g,ref:v,isValid:i,isInvalid:u,disabled:o,as:m});return f.jsx(ft.Provider,{value:E,children:f.jsx("div",{style:d,className:M(p,T&&t,r&&`${t}-inline`,l&&`${t}-reverse`,g==="switch"&&n),children:R||f.jsxs(f.Fragment,{children:[N,T&&f.jsx(Gi,{title:S,children:x}),a&&f.jsx(ld,{type:h,tooltip:s,children:a})]})})})});sd.displayName="FormCheck";const Gl=Object.assign(sd,{Input:id,Label:Gi}),ad=y.forwardRef(({bsPrefix:e,type:t,size:n,htmlSize:r,id:l,className:o,isValid:i=!1,isInvalid:u=!1,plaintext:s,readOnly:a,as:h="input",...p},d)=>{const{controlId:S}=y.useContext(ft);return e=H(e,"form-control"),f.jsx(h,{...p,type:t,size:r,ref:d,readOnly:a,id:l||S,className:M(o,s?`${e}-plaintext`:e,n&&`${e}-${n}`,t==="color"&&`${e}-color`,i&&"is-valid",u&&"is-invalid")})});ad.displayName="FormControl";const wv=Object.assign(ad,{Feedback:ld}),cd=y.forwardRef(({className:e,bsPrefix:t,as:n="div",...r},l)=>(t=H(t,"form-floating"),f.jsx(n,{ref:l,className:M(e,t),...r})));cd.displayName="FormFloating";const Sv=cd,fd=y.forwardRef(({controlId:e,as:t="div",...n},r)=>{const l=y.useMemo(()=>({controlId:e}),[e]);return f.jsx(ft.Provider,{value:l,children:f.jsx(t,{...n,ref:r})})});fd.displayName="FormGroup";const dd=fd,pd=y.forwardRef(({as:e="label",bsPrefix:t,column:n=!1,visuallyHidden:r=!1,className:l,htmlFor:o,...i},u)=>{const{controlId:s}=y.useContext(ft);t=H(t,"form-label");let a="col-form-label";typeof n=="string"&&(a=`${a} ${a}-${n}`);const h=M(l,t,r&&"visually-hidden",n&&a);return o=o||s,n?f.jsx(Vu,{ref:u,as:"label",className:h,htmlFor:o,...i}):f.jsx(e,{ref:u,className:h,htmlFor:o,...i})});pd.displayName="FormLabel";const xv=pd,md=y.forwardRef(({bsPrefix:e,className:t,id:n,...r},l)=>{const{controlId:o}=y.useContext(ft);return e=H(e,"form-range"),f.jsx("input",{...r,type:"range",ref:l,className:M(t,e),id:n||o})});md.displayName="FormRange";const kv=md,hd=y.forwardRef(({bsPrefix:e,size:t,htmlSize:n,className:r,isValid:l=!1,isInvalid:o=!1,id:i,...u},s)=>{const{controlId:a}=y.useContext(ft);return e=H(e,"form-select"),f.jsx("select",{...u,size:n,ref:s,className:M(r,e,t&&`${e}-${t}`,l&&"is-valid",o&&"is-invalid"),id:i||a})});hd.displayName="FormSelect";const Ev=hd,vd=y.forwardRef(({bsPrefix:e,className:t,as:n="small",muted:r,...l},o)=>(e=H(e,"form-text"),f.jsx(n,{...l,ref:o,className:M(t,e,r&&"text-muted")})));vd.displayName="FormText";const Cv=vd,yd=y.forwardRef((e,t)=>f.jsx(Gl,{...e,ref:t,type:"switch"}));yd.displayName="Switch";const Tv=Object.assign(yd,{Input:Gl.Input,Label:Gl.Label}),gd=y.forwardRef(({bsPrefix:e,className:t,children:n,controlId:r,label:l,...o},i)=>(e=H(e,"form-floating"),f.jsxs(dd,{ref:i,className:M(t,e),controlId:r,...o,children:[n,f.jsx("label",{htmlFor:r,children:l})]})));gd.displayName="FloatingLabel";const Nv=gd,_v={_ref:it.any,validated:it.bool,as:it.elementType},Gu=y.forwardRef(({className:e,validated:t,as:n="form",...r},l)=>f.jsx(n,{...r,ref:l,className:M(e,t&&"was-validated")}));Gu.displayName="Form";Gu.propTypes=_v;const Me=Object.assign(Gu,{Group:dd,Control:wv,Floating:Sv,Check:Gl,Switch:Tv,Label:xv,Text:Cv,Range:kv,Select:Ev,FloatingLabel:Nv});var ul;function pa(e){if((!ul&&ul!==0||e)&&Vn){var t=document.createElement("div");t.style.position="absolute",t.style.top="-9999px",t.style.width="50px",t.style.height="50px",t.style.overflow="scroll",document.body.appendChild(t),ul=t.offsetWidth-t.clientWidth,document.body.removeChild(t)}return ul}function Wo(e){e===void 0&&(e=po());try{var t=e.activeElement;return!t||!t.nodeName?null:t}catch{return e.body}}function jv(e=document){const t=e.defaultView;return Math.abs(t.innerWidth-e.documentElement.clientWidth)}const ma=vv("modal-open");class Rv{constructor({ownerDocument:t,handleContainerOverflow:n=!0,isRTL:r=!1}={}){this.handleContainerOverflow=n,this.isRTL=r,this.modals=[],this.ownerDocument=t}getScrollbarWidth(){return jv(this.ownerDocument)}getElement(){return(this.ownerDocument||document).body}setModalAttributes(t){}removeModalAttributes(t){}setContainerStyle(t){const n={overflow:"hidden"},r=this.isRTL?"paddingLeft":"paddingRight",l=this.getElement();t.style={overflow:l.style.overflow,[r]:l.style[r]},t.scrollBarWidth&&(n[r]=`${parseInt(Xt(l,r)||"0",10)+t.scrollBarWidth}px`),l.setAttribute(ma,""),Xt(l,n)}reset(){[...this.modals].forEach(t=>this.remove(t))}removeContainerStyle(t){const n=this.getElement();n.removeAttribute(ma),Object.assign(n.style,t.style)}add(t){let n=this.modals.indexOf(t);return n!==-1||(n=this.modals.length,this.modals.push(t),this.setModalAttributes(t),n!==0)||(this.state={scrollBarWidth:this.getScrollbarWidth(),style:{}},this.handleContainerOverflow&&this.setContainerStyle(this.state)),n}remove(t){const n=this.modals.indexOf(t);n!==-1&&(this.modals.splice(n,1),!this.modals.length&&this.handleContainerOverflow&&this.removeContainerStyle(this.state),this.removeModalAttributes(t))}isTopModal(t){return!!this.modals.length&&this.modals[this.modals.length-1]===t}}const Yu=Rv,Vo=(e,t)=>Vn?e==null?(t||po()).body:(typeof e=="function"&&(e=e()),e&&"current"in e&&(e=e.current),e&&("nodeType"in e||e.getBoundingClientRect)?e:null):null;function Lv(e,t){const n=Qu(),[r,l]=y.useState(()=>Vo(e,n==null?void 0:n.document));if(!r){const o=Vo(e);o&&l(o)}return y.useEffect(()=>{t&&r&&t(r)},[t,r]),y.useEffect(()=>{const o=Vo(e);o!==r&&l(o)},[e,r]),r}function Pv({children:e,in:t,onExited:n,mountOnEnter:r,unmountOnExit:l}){const o=y.useRef(null),i=y.useRef(t),u=Fe(n);y.useEffect(()=>{t?i.current=!0:u(o.current)},[t,u]);const s=mo(o,e.ref),a=y.cloneElement(e,{ref:s});return t?a:l||!i.current&&r?null:a}function Ov({in:e,onTransition:t}){const n=y.useRef(null),r=y.useRef(!0),l=Fe(t);return ca(()=>{if(!n.current)return;let o=!1;return l({in:e,element:n.current,initial:r.current,isStale:()=>o}),()=>{o=!0}},[e,l]),ca(()=>(r.current=!1,()=>{r.current=!0}),[]),n}function Fv({children:e,in:t,onExited:n,onEntered:r,transition:l}){const[o,i]=y.useState(!t);t&&o&&i(!1);const u=Ov({in:!!t,onTransition:a=>{const h=()=>{a.isStale()||(a.in?r==null||r(a.element,a.initial):(i(!0),n==null||n(a.element)))};Promise.resolve(l(a)).then(h,p=>{throw a.in||i(!0),p})}}),s=mo(u,e.ref);return o&&!t?null:y.cloneElement(e,{ref:s})}function ha(e,t,n){return e?f.jsx(e,Object.assign({},n)):t?f.jsx(Fv,Object.assign({},n,{transition:t})):f.jsx(Pv,Object.assign({},n))}function Mv(e){return e.code==="Escape"||e.keyCode===27}const zv=["show","role","className","style","children","backdrop","keyboard","onBackdropClick","onEscapeKeyDown","transition","runTransition","backdropTransition","runBackdropTransition","autoFocus","enforceFocus","restoreFocus","restoreFocusOptions","renderDialog","renderBackdrop","manager","container","onShow","onHide","onExit","onExited","onExiting","onEnter","onEntering","onEntered"];function $v(e,t){if(e==null)return{};var n={},r=Object.keys(e),l,o;for(o=0;o=0)&&(n[l]=e[l]);return n}let Qo;function Dv(e){return Qo||(Qo=new Yu({ownerDocument:e==null?void 0:e.document})),Qo}function Iv(e){const t=Qu(),n=e||Dv(t),r=y.useRef({dialog:null,backdrop:null});return Object.assign(r.current,{add:()=>n.add(r.current),remove:()=>n.remove(r.current),isTopModal:()=>n.isTopModal(r.current),setDialogRef:y.useCallback(l=>{r.current.dialog=l},[]),setBackdropRef:y.useCallback(l=>{r.current.backdrop=l},[])})}const wd=y.forwardRef((e,t)=>{let{show:n=!1,role:r="dialog",className:l,style:o,children:i,backdrop:u=!0,keyboard:s=!0,onBackdropClick:a,onEscapeKeyDown:h,transition:p,runTransition:d,backdropTransition:S,runBackdropTransition:g,autoFocus:x=!0,enforceFocus:R=!0,restoreFocus:m=!0,restoreFocusOptions:c,renderDialog:v,renderBackdrop:w=K=>f.jsx("div",Object.assign({},K)),manager:E,container:T,onShow:N,onHide:j=()=>{},onExit:U,onExited:O,onExiting:ie,onEnter:Ke,onEntering:Ge,onEntered:on}=e,Qn=$v(e,zv);const je=Qu(),Ye=Lv(T),C=Iv(E),L=Yh(),P=Xh(n),[D,A]=y.useState(!n),fe=y.useRef(null);y.useImperativeHandle(t,()=>C,[C]),Vn&&!P&&n&&(fe.current=Wo(je==null?void 0:je.document)),n&&D&&A(!1);const Re=Fe(()=>{if(C.add(),sn.current=Ql(document,"keydown",ho),un.current=Ql(document,"focus",()=>setTimeout(Le),!0),N&&N(),x){var K,Hr;const Yn=Wo((K=(Hr=C.dialog)==null?void 0:Hr.ownerDocument)!=null?K:je==null?void 0:je.document);C.dialog&&Yn&&!da(C.dialog,Yn)&&(fe.current=Yn,C.dialog.focus())}}),et=Fe(()=>{if(C.remove(),sn.current==null||sn.current(),un.current==null||un.current(),m){var K;(K=fe.current)==null||K.focus==null||K.focus(c),fe.current=null}});y.useEffect(()=>{!n||!Ye||Re()},[n,Ye,Re]),y.useEffect(()=>{D&&et()},[D,et]),ed(()=>{et()});const Le=Fe(()=>{if(!R||!L()||!C.isTopModal())return;const K=Wo(je==null?void 0:je.document);C.dialog&&K&&!da(C.dialog,K)&&C.dialog.focus()}),mt=Fe(K=>{K.target===K.currentTarget&&(a==null||a(K),u===!0&&j())}),ho=Fe(K=>{s&&Mv(K)&&C.isTopModal()&&(h==null||h(K),K.defaultPrevented||j())}),un=y.useRef(),sn=y.useRef(),Kn=(...K)=>{A(!0),O==null||O(...K)};if(!Ye)return null;const Br=Object.assign({role:r,ref:C.setDialogRef,"aria-modal":r==="dialog"?!0:void 0},Qn,{style:o,className:l,tabIndex:-1});let Gn=v?v(Br):f.jsx("div",Object.assign({},Br,{children:y.cloneElement(i,{role:"document"})}));Gn=ha(p,d,{unmountOnExit:!0,mountOnEnter:!0,appear:!0,in:!!n,onExit:U,onExiting:ie,onExited:Kn,onEnter:Ke,onEntering:Ge,onEntered:on,children:Gn});let It=null;return u&&(It=w({ref:C.setBackdropRef,onClick:mt}),It=ha(S,g,{in:!!n,appear:!0,mountOnEnter:!0,unmountOnExit:!0,children:It})),f.jsx(f.Fragment,{children:Nn.createPortal(f.jsxs(f.Fragment,{children:[It,Gn]}),Ye)})});wd.displayName="Modal";const Av=Object.assign(wd,{Manager:Yu});function Uv(e,t){return e.classList?!!t&&e.classList.contains(t):(" "+(e.className.baseVal||e.className)+" ").indexOf(" "+t+" ")!==-1}function Bv(e,t){e.classList?e.classList.add(t):Uv(e,t)||(typeof e.className=="string"?e.className=e.className+" "+t:e.setAttribute("class",(e.className&&e.className.baseVal||"")+" "+t))}function va(e,t){return e.replace(new RegExp("(^|\\s)"+t+"(?:\\s|$)","g"),"$1").replace(/\s+/g," ").replace(/^\s*|\s*$/g,"")}function Hv(e,t){e.classList?e.classList.remove(t):typeof e.className=="string"?e.className=va(e.className,t):e.setAttribute("class",va(e.className&&e.className.baseVal||"",t))}const pn={FIXED_CONTENT:".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",STICKY_CONTENT:".sticky-top",NAVBAR_TOGGLER:".navbar-toggler"};class Wv extends Yu{adjustAndStore(t,n,r){const l=n.style[t];n.dataset[t]=l,Xt(n,{[t]:`${parseFloat(Xt(n,t))+r}px`})}restore(t,n){const r=n.dataset[t];r!==void 0&&(delete n.dataset[t],Xt(n,{[t]:r}))}setContainerStyle(t){super.setContainerStyle(t);const n=this.getElement();if(Bv(n,"modal-open"),!t.scrollBarWidth)return;const r=this.isRTL?"paddingLeft":"paddingRight",l=this.isRTL?"marginLeft":"marginRight";dn(n,pn.FIXED_CONTENT).forEach(o=>this.adjustAndStore(r,o,t.scrollBarWidth)),dn(n,pn.STICKY_CONTENT).forEach(o=>this.adjustAndStore(l,o,-t.scrollBarWidth)),dn(n,pn.NAVBAR_TOGGLER).forEach(o=>this.adjustAndStore(l,o,t.scrollBarWidth))}removeContainerStyle(t){super.removeContainerStyle(t);const n=this.getElement();Hv(n,"modal-open");const r=this.isRTL?"paddingLeft":"paddingRight",l=this.isRTL?"marginLeft":"marginRight";dn(n,pn.FIXED_CONTENT).forEach(o=>this.restore(r,o)),dn(n,pn.STICKY_CONTENT).forEach(o=>this.restore(l,o)),dn(n,pn.NAVBAR_TOGGLER).forEach(o=>this.restore(l,o))}}let Ko;function Vv(e){return Ko||(Ko=new Wv(e)),Ko}const Sd=y.forwardRef(({className:e,bsPrefix:t,as:n="div",...r},l)=>(t=H(t,"modal-body"),f.jsx(n,{ref:l,className:M(e,t),...r})));Sd.displayName="ModalBody";const Qv=Sd,Kv=y.createContext({onHide(){}}),xd=Kv,kd=y.forwardRef(({bsPrefix:e,className:t,contentClassName:n,centered:r,size:l,fullscreen:o,children:i,scrollable:u,...s},a)=>{e=H(e,"modal");const h=`${e}-dialog`,p=typeof o=="string"?`${e}-fullscreen-${o}`:`${e}-fullscreen`;return f.jsx("div",{...s,ref:a,className:M(h,t,l&&`${e}-${l}`,r&&`${h}-centered`,u&&`${h}-scrollable`,o&&p),children:f.jsx("div",{className:M(`${e}-content`,n),children:i})})});kd.displayName="ModalDialog";const Ed=kd,Cd=y.forwardRef(({className:e,bsPrefix:t,as:n="div",...r},l)=>(t=H(t,"modal-footer"),f.jsx(n,{ref:l,className:M(e,t),...r})));Cd.displayName="ModalFooter";const Gv=Cd,Yv=y.forwardRef(({closeLabel:e="Close",closeVariant:t,closeButton:n=!1,onHide:r,children:l,...o},i)=>{const u=y.useContext(xd),s=Fe(()=>{u==null||u.onHide(),r==null||r()});return f.jsxs("div",{ref:i,...o,children:[l,n&&f.jsx(Jf,{"aria-label":e,variant:t,onClick:s})]})}),Xv=Yv,Td=y.forwardRef(({bsPrefix:e,className:t,closeLabel:n="Close",closeButton:r=!1,...l},o)=>(e=H(e,"modal-header"),f.jsx(Xv,{ref:o,...l,className:M(t,e),closeLabel:n,closeButton:r})));Td.displayName="ModalHeader";const Zv=Td,Jv=Qf("h4"),Nd=y.forwardRef(({className:e,bsPrefix:t,as:n=Jv,...r},l)=>(t=H(t,"modal-title"),f.jsx(n,{ref:l,className:M(e,t),...r})));Nd.displayName="ModalTitle";const qv=Nd;function bv(e){return f.jsx(Kl,{...e,timeout:null})}function ey(e){return f.jsx(Kl,{...e,timeout:null})}const _d=y.forwardRef(({bsPrefix:e,className:t,style:n,dialogClassName:r,contentClassName:l,children:o,dialogAs:i=Ed,"aria-labelledby":u,"aria-describedby":s,"aria-label":a,show:h=!1,animation:p=!0,backdrop:d=!0,keyboard:S=!0,onEscapeKeyDown:g,onShow:x,onHide:R,container:m,autoFocus:c=!0,enforceFocus:v=!0,restoreFocus:w=!0,restoreFocusOptions:E,onEntered:T,onExit:N,onExiting:j,onEnter:U,onEntering:O,onExited:ie,backdropClassName:Ke,manager:Ge,...on},Qn)=>{const[je,Ye]=y.useState({}),[C,L]=y.useState(!1),P=y.useRef(!1),D=y.useRef(!1),A=y.useRef(null),[fe,Re]=Gh(),et=mo(Qn,Re),Le=Fe(R),mt=xh();e=H(e,"modal");const ho=y.useMemo(()=>({onHide:Le}),[Le]);function un(){return Ge||Vv({isRTL:mt})}function sn($){if(!Vn)return;const an=un().getScrollbarWidth()>0,Zu=$.scrollHeight>po($).documentElement.clientHeight;Ye({paddingRight:an&&!Zu?pa():void 0,paddingLeft:!an&&Zu?pa():void 0})}const Kn=Fe(()=>{fe&&sn(fe.dialog)});ed(()=>{Ki(window,"resize",Kn),A.current==null||A.current()});const Br=()=>{P.current=!0},Gn=$=>{P.current&&fe&&$.target===fe.dialog&&(D.current=!0),P.current=!1},It=()=>{L(!0),A.current=Vf(fe.dialog,()=>{L(!1)})},K=$=>{$.target===$.currentTarget&&It()},Hr=$=>{if(d==="static"){K($);return}if(D.current||$.target!==$.currentTarget){D.current=!1;return}R==null||R()},Yn=$=>{S?g==null||g($):($.preventDefault(),d==="static"&&It())},Dd=($,an)=>{$&&sn($),U==null||U($,an)},Id=$=>{A.current==null||A.current(),N==null||N($)},Ad=($,an)=>{O==null||O($,an),Wf(window,"resize",Kn)},Ud=$=>{$&&($.style.display=""),ie==null||ie($),Ki(window,"resize",Kn)},Bd=y.useCallback($=>f.jsx("div",{...$,className:M(`${e}-backdrop`,Ke,!p&&"show")}),[p,Ke,e]),Xu={...n,...je};Xu.display="block";const Hd=$=>f.jsx("div",{role:"dialog",...$,style:Xu,className:M(t,e,C&&`${e}-static`,!p&&"show"),onClick:d?Hr:void 0,onMouseUp:Gn,"aria-label":a,"aria-labelledby":u,"aria-describedby":s,children:f.jsx(i,{...on,onMouseDown:Br,className:r,contentClassName:l,children:o})});return f.jsx(xd.Provider,{value:ho,children:f.jsx(Av,{show:h,ref:et,backdrop:d,container:m,keyboard:!0,autoFocus:c,enforceFocus:v,restoreFocus:w,restoreFocusOptions:E,onEscapeKeyDown:Yn,onShow:x,onHide:R,onEnter:Dd,onEntering:Ad,onEntered:T,onExit:Id,onExiting:j,onExited:Ud,manager:un(),transition:p?bv:void 0,backdropTransition:p?ey:void 0,renderBackdrop:Bd,renderDialog:Hd})})});_d.displayName="Modal";const ye=Object.assign(_d,{Body:Qv,Header:Zv,Title:qv,Footer:Gv,Dialog:Ed,TRANSITION_DURATION:300,BACKDROP_TRANSITION_DURATION:150}),ya=1e3;function ty(e,t,n){const r=(e-t)/(n-t)*100;return Math.round(r*ya)/ya}function ga({min:e,now:t,max:n,label:r,visuallyHidden:l,striped:o,animated:i,className:u,style:s,variant:a,bsPrefix:h,...p},d){return f.jsx("div",{ref:d,...p,role:"progressbar",className:M(u,`${h}-bar`,{[`bg-${a}`]:a,[`${h}-bar-animated`]:i,[`${h}-bar-striped`]:i||o}),style:{width:`${ty(t,e,n)}%`,...s},"aria-valuenow":t,"aria-valuemin":e,"aria-valuemax":n,children:l?f.jsx("span",{className:"visually-hidden",children:r}):r})}const jd=y.forwardRef(({isChild:e=!1,...t},n)=>{const r={min:0,max:100,animated:!1,visuallyHidden:!1,striped:!1,...t};if(r.bsPrefix=H(r.bsPrefix,"progress"),e)return ga(r,n);const{min:l,now:o,max:i,label:u,visuallyHidden:s,striped:a,animated:h,bsPrefix:p,variant:d,className:S,children:g,...x}=r;return f.jsx("div",{ref:n,...x,className:M(S,p),children:g?cv(g,R=>y.cloneElement(R,{isChild:!0})):ga({min:l,now:o,max:i,label:u,visuallyHidden:s,striped:a,animated:h,bsPrefix:p,variant:d},n)})});jd.displayName="ProgressBar";const ny=jd,Rd=y.forwardRef(({bsPrefix:e,className:t,as:n="div",...r},l)=>{const o=H(e,"row"),i=Df(),u=If(),s=`${o}-cols`,a=[];return i.forEach(h=>{const p=r[h];delete r[h];let d;p!=null&&typeof p=="object"?{cols:d}=p:d=p;const S=h!==u?`-${h}`:"";d!=null&&a.push(`${s}${S}-${d}`)}),f.jsx(n,{ref:l,...r,className:M(t,o,...a)})});Rd.displayName="Row";const Ld=Rd,Pd=y.forwardRef(({bsPrefix:e,variant:t,animation:n="border",size:r,as:l="div",className:o,...i},u)=>{e=H(e,"spinner");const s=`${e}-${n}`;return f.jsx(l,{ref:u,...i,className:M(o,s,r&&`${s}-${r}`,t&&`text-${t}`)})});Pd.displayName="Spinner";const Un=Pd,Sl="initializing",wa="paused",Od="live",ry="error",ln=y.createContext({listTorrents:function(){throw new Error("Function not implemented.")},getTorrentDetails:function(e){throw new Error("Function not implemented.")},getTorrentStats:function(e){throw new Error("Function not implemented.")},uploadTorrent:function(e,t){throw new Error("Function not implemented.")},pause:function(e){throw new Error("Function not implemented.")},start:function(e){throw new Error("Function not implemented.")},forget:function(e){throw new Error("Function not implemented.")},delete:function(e){throw new Error("Function not implemented.")}}),Ur=y.createContext({setCloseableError:e=>{},refreshTorrents:()=>{}}),Fd=y.createContext({refresh:()=>{}}),Go=({className:e,onClick:t,disabled:n,color:r})=>{const l=o=>{o.stopPropagation(),!n&&t()};return f.jsx("a",{className:`bi ${e} p-1`,onClick:l,href:"#"})},ly=({id:e,show:t,onHide:n})=>{if(!t)return null;const[r,l]=y.useState(!1),[o,i]=y.useState(null),[u,s]=y.useState(!1),a=y.useContext(Ur),h=y.useContext(ln),p=()=>{l(!1),i(null),s(!1),n()},d=()=>{s(!0),(r?h.delete:h.forget)(e).then(()=>{a.refreshTorrents(),p()}).catch(g=>{i({text:`Error deleting torrent id=${e}`,details:g}),s(!1)})};return f.jsxs(ye,{show:t,onHide:p,children:[f.jsx(ye.Header,{closeButton:!0,children:"Delete torrent"}),f.jsxs(ye.Body,{children:[f.jsx(Me,{children:f.jsx(Me.Group,{controlId:"delete-torrent",children:f.jsx(Me.Check,{type:"checkbox",label:"Also delete files",checked:r,onChange:()=>l(!r)})})}),o&&f.jsx(Mr,{error:o})]}),f.jsxs(ye.Footer,{children:[u&&f.jsx(Un,{}),f.jsx(tn,{variant:"primary",onClick:d,disabled:u,children:"OK"}),f.jsx(tn,{variant:"secondary",onClick:p,children:"Cancel"})]})]})},oy=({id:e,statsResponse:t})=>{let n=t.state,[r,l]=y.useState(!1),[o,i]=y.useState(!1),u=y.useContext(Fd);const s=n=="live",a=n=="paused"||n=="error",h=y.useContext(Ur),p=y.useContext(ln),d=()=>{l(!0),p.start(e).then(()=>{u.refresh()},R=>{h.setCloseableError({text:`Error starting torrent id=${e}`,details:R})}).finally(()=>l(!1))},S=()=>{l(!0),p.pause(e).then(()=>{u.refresh()},R=>{h.setCloseableError({text:`Error pausing torrent id=${e}`,details:R})}).finally(()=>l(!1))},g=()=>{l(!0),i(!0)},x=()=>{l(!1),i(!1)};return f.jsx(Ld,{children:f.jsxs(Vu,{children:[a&&f.jsx(Go,{className:"bi-play-circle",onClick:d,disabled:r,color:"success"}),s&&f.jsx(Go,{className:"bi-pause-circle",onClick:S,disabled:r}),f.jsx(Go,{className:"bi-x-circle",onClick:g,disabled:r,color:"danger"}),f.jsx(ly,{id:e,show:o,onHide:x})]})})},iy=({id:e,detailsResponse:t,statsResponse:n})=>{const r=(n==null?void 0:n.state)??"",l=n==null?void 0:n.error,o=(n==null?void 0:n.total_bytes)??1,i=(n==null?void 0:n.progress_bytes)??0,u=(n==null?void 0:n.finished)||!1,s=l?100:i/o*100,a=(r==Sl||r==Od)&&!u,h=l?"Error":`${s.toFixed(2)}%`,p=l?"danger":u?"success":r==Sl?"warning":"primary",d=()=>{var R;let x=(R=n==null?void 0:n.live)==null?void 0:R.snapshot.peer_stats;return x?`${x.live} / ${x.seen}`:""},S=()=>{var x;if(u)return"Completed";switch(r){case wa:return"Paused";case Sl:return"Checking files";case ry:return"Error"}return((x=n==null?void 0:n.live)==null?void 0:x.download_speed.human_readable)??"N/A"};let g=[];return l?g.push("bg-warning"):e%2==0&&g.push("bg-light"),f.jsxs(Ld,{className:g.join(" "),children:[f.jsx(vt,{size:3,label:"Name",children:t?f.jsxs(f.Fragment,{children:[f.jsx("div",{className:"text-truncate",children:yy(t)}),l&&f.jsxs("p",{className:"text-danger",children:[f.jsx("strong",{children:"Error:"})," ",l]})]}):f.jsx(Un,{})}),n?f.jsxs(f.Fragment,{children:[f.jsx(vt,{label:"Size",children:`${zd(o)} `}),f.jsx(vt,{size:2,label:(r==wa,"Progress"),children:f.jsx(ny,{now:s,label:h,animated:a,variant:p})}),f.jsx(vt,{size:2,label:"Down Speed",children:S()}),f.jsx(vt,{label:"ETA",children:gy(n)}),f.jsx(vt,{size:2,label:"Peers",children:d()}),f.jsx(vt,{label:"Actions",children:f.jsx(oy,{id:e,statsResponse:n})})]}):f.jsx(vt,{label:"Loading stats",size:8,children:f.jsx(Un,{})})]})},vt=({size:e,label:t,children:n})=>f.jsxs(Vu,{md:e||1,className:"py-3",children:[f.jsx("div",{className:"fw-bold",children:t}),n]}),uy=({id:e,torrent:t})=>{const[n,r]=y.useState(null),[l,o]=y.useState(null),[i,u]=y.useState(0),s=y.useContext(ln),a=()=>{u(i+1)};return y.useEffect(()=>{if(n===null)return Sy(async()=>{await s.getTorrentDetails(t.id).then(r)},1e3)},[n]),y.useEffect(()=>$d(async()=>s.getTorrentStats(t.id).then(g=>(o(g),g)).then(g=>g.finished?1e4:g.state==Sl||g.state==Od?1e3:1e4,g=>1e4),0),[i]),f.jsx(Fd.Provider,{value:{refresh:a},children:f.jsx(iy,{id:e,detailsResponse:n,statsResponse:l})})},sy=e=>{if(e.torrents===null&&e.loading)return f.jsx(Un,{});if(e.torrents!==null)return e.torrents.length===0?f.jsx("div",{className:"text-center",children:f.jsx("p",{children:"No existing torrents found. Add them through buttons below."})}):f.jsx(f.Fragment,{children:e.torrents.map(t=>f.jsx(uy,{id:t.id,torrent:t},t.id))})},ay=()=>{const[e,t]=y.useState(null),[n,r]=y.useState(null),[l,o]=y.useState(null),[i,u]=y.useState(!1),s=y.useContext(ln),a=async()=>{u(!0);let p=await s.listTorrents().finally(()=>u(!1));o(p.torrents)};y.useEffect(()=>$d(async()=>a().then(()=>(r(null),5e3),p=>(r({text:"Error refreshing torrents",details:p}),console.error(p),5e3)),0),[]);const h={setCloseableError:t,refreshTorrents:a};return f.jsx(Ur.Provider,{value:h,children:f.jsxs("div",{className:"text-center",children:[f.jsx("h1",{className:"mt-3 mb-4",children:"rqbit web 4.0.0-beta.0"}),f.jsx(vy,{closeableError:e,otherError:n,torrents:l,torrentsLoading:i})]})})},cy=e=>{let{details:t}=e;return t?f.jsxs(f.Fragment,{children:[f.jsx("p",{children:t.status&&f.jsxs("strong",{children:[t.status," ",t.statusText]})}),f.jsx("pre",{children:t.text})]}):null},Mr=e=>{let{error:t,remove:n}=e;return t==null?null:f.jsxs(fa,{variant:"danger",onClose:n,dismissible:n!=null,children:[f.jsx(fa.Heading,{children:t.text}),f.jsx(cy,{details:t.details})]})},Md=({buttonText:e,onClick:t,data:n,resetData:r,variant:l})=>{const[o,i]=y.useState(!1),[u,s]=y.useState(null),[a,h]=y.useState(null),p=y.useContext(ln);y.useEffect(()=>{if(n===null)return;let S=setTimeout(async()=>{i(!0);try{const g=await p.uploadTorrent(n,{listOnly:!0});s(g)}catch(g){h({text:"Error listing torrent files",details:g})}finally{i(!1)}},0);return()=>clearTimeout(S)},[n]);const d=()=>{r(),h(null),s(null),i(!1)};return f.jsxs(f.Fragment,{children:[f.jsx(tn,{variant:l,onClick:t,className:"m-1",children:e}),n&&f.jsx(my,{onHide:d,listTorrentError:a,listTorrentResponse:u,data:n,listTorrentLoading:o})]})},fy=({show:e,setUrl:t,cancel:n})=>{let[r,l]=y.useState("");return f.jsxs(ye,{show:e,onHide:n,size:"lg",children:[f.jsx(ye.Header,{closeButton:!0,children:f.jsx(ye.Title,{children:"Add torrent"})}),f.jsx(ye.Body,{children:f.jsx(Me,{children:f.jsxs(Me.Group,{className:"mb-3",controlId:"url",children:[f.jsx(Me.Label,{children:"Enter magnet or HTTP(S) URL to the .torrent"}),f.jsx(Me.Control,{value:r,placeholder:"magnet:?xt=urn:btih:...",onChange:o=>{l(o.target.value)}})]})})}),f.jsxs(ye.Footer,{children:[f.jsx(tn,{variant:"primary",onClick:()=>{t(r),l("")},disabled:r.length==0,children:"OK"}),f.jsx(tn,{variant:"secondary",onClick:n,children:"Cancel"})]})]})},dy=()=>{let[e,t]=y.useState(null),[n,r]=y.useState(!1);return f.jsxs(f.Fragment,{children:[f.jsx(Md,{variant:"primary",buttonText:"Add Torrent from Magnet / URL",onClick:()=>{r(!0)},data:e,resetData:()=>t(null)}),f.jsx(fy,{show:n,setUrl:l=>{r(!1),t(l)},cancel:()=>{r(!1),t(null)}})]})},py=()=>{const e=y.useRef(),[t,n]=y.useState(null),r=async()=>{var u;if(!((u=e==null?void 0:e.current)!=null&&u.files))return;const i=e.current.files[0];n(i)},l=()=>{e!=null&&e.current&&(e.current.value="",n(null))},o=()=>{e!=null&&e.current&&e.current.click()};return f.jsxs(f.Fragment,{children:[f.jsx("input",{type:"file",ref:e,accept:".torrent",onChange:r,className:"d-none"}),f.jsx(Md,{variant:"secondary",buttonText:"Upload .torrent File",onClick:o,data:t,resetData:l})]})},my=e=>{let{onHide:t,listTorrentResponse:n,listTorrentError:r,listTorrentLoading:l,data:o}=e;const[i,u]=y.useState([]),[s,a]=y.useState(!1),[h,p]=y.useState(null),[d,S]=y.useState(!1),g=y.useContext(Ur),x=y.useContext(ln);y.useEffect(()=>{u(n?n.details.files.map((w,E)=>E):[])},[n]);const R=()=>{t(),u([]),p(null),a(!1)},m=w=>{i.includes(w)?u(i.filter(E=>E!==w)):u([...i,w])},c=async()=>{if(!n)return;a(!0);let w=n.seen_peers?n.seen_peers.slice(0,32):null;x.uploadTorrent(o,{selectedFiles:i,unpopularTorrent:d,initialPeers:w}).then(()=>{t(),g.refreshTorrents()},E=>{p({text:"Error starting torrent",details:E})}).finally(()=>a(!1))},v=()=>{if(l)return f.jsx(Un,{});if(r)return f.jsx(Mr,{error:r});if(n)return f.jsxs(Me,{children:[f.jsxs("fieldset",{className:"mb-5",children:[f.jsx("legend",{children:"Pick the files to download"}),n.details.files.map((w,E)=>f.jsx(Me.Group,{controlId:`check-${E}`,children:f.jsx(Me.Check,{type:"checkbox",label:`${w.name} (${zd(w.length)})`,checked:i.includes(E),onChange:()=>m(E)})},E))]}),f.jsxs("fieldset",{children:[f.jsx("legend",{children:"Other options"}),f.jsxs(Me.Group,{controlId:"unpopular-torrent",children:[f.jsx(Me.Check,{type:"checkbox",label:"Increase timeouts",checked:d,onChange:()=>S(!d)}),f.jsx("small",{id:"emailHelp",className:"form-text text-muted",children:"This might be useful for unpopular torrents with few peers. It will slow down fast torrents though."})]})]})]})};return f.jsxs(ye,{show:!0,onHide:R,size:"lg",children:[f.jsx(ye.Header,{closeButton:!0,children:f.jsx(ye.Title,{children:"Add torrent"})}),f.jsxs(ye.Body,{children:[v(),f.jsx(Mr,{error:h})]}),f.jsxs(ye.Footer,{children:[s&&f.jsx(Un,{}),f.jsx(tn,{variant:"primary",onClick:c,disabled:l||s||i.length==0,children:"OK"}),f.jsx(tn,{variant:"secondary",onClick:R,children:"Cancel"})]})]})},hy=()=>f.jsxs("div",{id:"buttons-container",className:"mt-3",children:[f.jsx(dy,{}),f.jsx(py,{})]}),vy=e=>{let t=y.useContext(Ur);return f.jsxs(pv,{children:[f.jsx(Mr,{error:e.closeableError,remove:()=>t.setCloseableError(null)}),f.jsx(Mr,{error:e.otherError}),f.jsx(sy,{torrents:e.torrents,loading:e.torrentsLoading}),f.jsx(hy,{})]})};function zd(e){if(e===0)return"0 Bytes";const t=1024,n=["Bytes","KB","MB","GB"],r=Math.floor(Math.log(e)/Math.log(t));return parseFloat((e/Math.pow(t,r)).toFixed(2))+" "+n[r]}function yy(e){return e.files.filter(n=>n.included).reduce((n,r)=>n.length>r.length?n:r).name}function gy(e){var n,r,l;let t=(l=(r=(n=e==null?void 0:e.live)==null?void 0:n.time_remaining)==null?void 0:r.duration)==null?void 0:l.secs;return t==null?"N/A":wy(t)}function wy(e){const t=Math.floor(e/3600),n=Math.floor(e%3600/60),r=e%60,l=(o,i)=>o>0?`${o}${i}`:"";return t>0?`${l(t,"h")} ${l(n,"m")}`.trim():n>0?`${l(n,"m")} ${l(r,"s")}`.trim():`${l(r,"s")}`.trim()}function $d(e,t){let n,r=t;const l=async()=>{if(r=await e(),r==null)throw"asyncCallback returned null or undefined";o()};let o=()=>{n=setTimeout(l,r)};return o(),()=>{clearTimeout(n)}}function Sy(e,t){let n;const r=async()=>{await e().then(()=>!1,()=>!0)&&l()};let l=o=>{n=setTimeout(r,o!==void 0?o:t)};return l(0),()=>clearTimeout(n)}const xy=window.origin==="null"||window.origin==="http://localhost:3031"?"http://localhost:3030":"",yt=async(e,t,n)=>{console.log(e,t);const r=xy+t,l={method:e,headers:{Accept:"application/json"},body:n};let o={method:e,path:t,text:""},i;try{i=await fetch(r,l)}catch{return o.text="network error",Promise.reject(o)}if(o.status=i.status,o.statusText=i.statusText,!i.ok){const s=await i.text();try{const a=JSON.parse(s);o.text=a.human_readable!==void 0?a.human_readable:JSON.stringify(a,null,2)}catch{o.text=s}return Promise.reject(o)}return await i.json()},ky={listTorrents:()=>yt("GET","/torrents"),getTorrentDetails:e=>yt("GET",`/torrents/${e}`),getTorrentStats:e=>yt("GET",`/torrents/${e}/stats/v1`),uploadTorrent:(e,t)=>{t=t||{};let n="/torrents?&overwrite=true";return t.listOnly&&(n+="&list_only=true"),t.selectedFiles!=null&&(n+=`&only_files=${t.selectedFiles.join(",")}`),t.unpopularTorrent&&(n+="&peer_connect_timeout=20&peer_read_write_timeout=60"),t.initialPeers&&(n+=`&initial_peers=${t.initialPeers.join(",")}`),typeof e=="string"&&(n+="&is_url=true"),yt("POST",n,e)},pause:e=>yt("POST",`/torrents/${e}/pause`),start:e=>yt("POST",`/torrents/${e}/start`),forget:e=>yt("POST",`/torrents/${e}/forget`),delete:e=>yt("POST",`/torrents/${e}/delete`)};Yo.createRoot(document.getElementById("app")).render(f.jsx(y.StrictMode,{children:f.jsx(ln.Provider,{value:ky,children:f.jsx(ay,{})})})); +*/(function(e){(function(){var t={}.hasOwnProperty;function n(){for(var r=[],l=0;l=0)&&(n[l]=e[l]);return n}function ia(e){return"default"+e.charAt(0).toUpperCase()+e.substr(1)}function mh(e){var t=hh(e,"string");return typeof t=="symbol"?t:String(t)}function hh(e,t){if(typeof e!="object"||e===null)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||"default");if(typeof r!="object")return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return(t==="string"?String:Number)(e)}function vh(e,t,n){var r=y.useRef(e!==void 0),l=y.useState(t),o=l[0],i=l[1],u=e!==void 0,s=r.current;return r.current=u,!u&&s&&o!==t&&i(t),[u?e:o,y.useCallback(function(a){for(var h=arguments.length,p=new Array(h>1?h-1:0),d=1;d{o.target===e&&(l(),t(o))},n+r)}function Uh(e){e.offsetHeight}const aa=e=>!e||typeof e=="function"?e:t=>{e.current=t};function Bh(e,t){const n=aa(e),r=aa(t);return l=>{n&&n(l),r&&r(l)}}function mo(e,t){return y.useMemo(()=>Bh(e,t),[e,t])}function Hh(e){return e&&"setState"in e?Nn.findDOMNode(e):e??null}const Wh=Wt.forwardRef(({onEnter:e,onEntering:t,onEntered:n,onExit:r,onExiting:l,onExited:o,addEndListener:i,children:u,childRef:s,...a},h)=>{const p=y.useRef(null),d=mo(p,s),S=T=>{d(Hh(T))},g=T=>N=>{T&&p.current&&T(p.current,N)},x=y.useCallback(g(e),[e]),R=y.useCallback(g(t),[t]),m=y.useCallback(g(n),[n]),c=y.useCallback(g(r),[r]),v=y.useCallback(g(l),[l]),w=y.useCallback(g(o),[o]),E=y.useCallback(g(i),[i]);return f.jsx(zh,{ref:h,...a,onEnter:x,onEntered:m,onEntering:R,onExit:c,onExited:w,onExiting:v,addEndListener:E,nodeRef:p,children:typeof u=="function"?(T,N)=>u(T,{...N,ref:S}):Wt.cloneElement(u,{ref:S})})}),Vh=Wh;function Qh(e){const t=y.useRef(e);return y.useEffect(()=>{t.current=e},[e]),t}function Fe(e){const t=Qh(e);return y.useCallback(function(...n){return t.current&&t.current(...n)},[t])}const Qf=e=>y.forwardRef((t,n)=>f.jsx("div",{...t,ref:n,className:M(t.className,e)})),Kf=Qf("h4");Kf.displayName="DivStyledAsH4";const Gf=y.forwardRef(({className:e,bsPrefix:t,as:n=Kf,...r},l)=>(t=H(t,"alert-heading"),f.jsx(n,{ref:l,className:M(e,t),...r})));Gf.displayName="AlertHeading";const Kh=Gf;function Gh(){return y.useState(null)}function Yh(){const e=y.useRef(!0),t=y.useRef(()=>e.current);return y.useEffect(()=>(e.current=!0,()=>{e.current=!1}),[]),t.current}function Xh(e){const t=y.useRef(null);return y.useEffect(()=>{t.current=e}),t.current}const Zh=typeof global<"u"&&global.navigator&&global.navigator.product==="ReactNative",Jh=typeof document<"u",ca=Jh||Zh?y.useLayoutEffect:y.useEffect,qh=["as","disabled"];function bh(e,t){if(e==null)return{};var n={},r=Object.keys(e),l,o;for(o=0;o=0)&&(n[l]=e[l]);return n}function ev(e){return!e||e.trim()==="#"}function Hu({tagName:e,disabled:t,href:n,target:r,rel:l,role:o,onClick:i,tabIndex:u=0,type:s}){e||(n!=null||r!=null||l!=null?e="a":e="button");const a={tagName:e};if(e==="button")return[{type:s||"button",disabled:t},a];const h=d=>{if((t||e==="a"&&ev(n))&&d.preventDefault(),t){d.stopPropagation();return}i==null||i(d)},p=d=>{d.key===" "&&(d.preventDefault(),h(d))};return e==="a"&&(n||(n="#"),t&&(n=void 0)),[{role:o??"button",disabled:void 0,tabIndex:t?void 0:u,href:n,target:e==="a"?r:void 0,"aria-disabled":t||void 0,rel:e==="a"?l:void 0,onClick:h,onKeyDown:p},a]}const tv=y.forwardRef((e,t)=>{let{as:n,disabled:r}=e,l=bh(e,qh);const[o,{tagName:i}]=Hu(Object.assign({tagName:n,disabled:r},l));return f.jsx(i,Object.assign({},l,o,{ref:t}))});tv.displayName="Button";const nv=["onKeyDown"];function rv(e,t){if(e==null)return{};var n={},r=Object.keys(e),l,o;for(o=0;o=0)&&(n[l]=e[l]);return n}function lv(e){return!e||e.trim()==="#"}const Yf=y.forwardRef((e,t)=>{let{onKeyDown:n}=e,r=rv(e,nv);const[l]=Hu(Object.assign({tagName:"a"},r)),o=Fe(i=>{l.onKeyDown(i),n==null||n(i)});return lv(r.href)||r.role==="button"?f.jsx("a",Object.assign({ref:t},r,l,{onKeyDown:o})):f.jsx("a",Object.assign({ref:t},r,{onKeyDown:n}))});Yf.displayName="Anchor";const ov=Yf,Xf=y.forwardRef(({className:e,bsPrefix:t,as:n=ov,...r},l)=>(t=H(t,"alert-link"),f.jsx(n,{ref:l,className:M(e,t),...r})));Xf.displayName="AlertLink";const iv=Xf,uv={[St]:"show",[Ht]:"show"},Zf=y.forwardRef(({className:e,children:t,transitionClasses:n={},onEnter:r,...l},o)=>{const i={in:!1,timeout:300,mountOnEnter:!1,unmountOnExit:!1,appear:!1,...l},u=y.useCallback((s,a)=>{Uh(s),r==null||r(s,a)},[r]);return f.jsx(Vh,{ref:o,addEndListener:Ah,...i,onEnter:u,childRef:t.ref,children:(s,a)=>y.cloneElement(t,{...a,className:M("fade",e,t.props.className,uv[s],n[s])})})});Zf.displayName="Fade";const Kl=Zf,sv={"aria-label":it.string,onClick:it.func,variant:it.oneOf(["white"])},Wu=y.forwardRef(({className:e,variant:t,"aria-label":n="Close",...r},l)=>f.jsx("button",{ref:l,type:"button",className:M("btn-close",t&&`btn-close-${t}`,e),"aria-label":n,...r}));Wu.displayName="CloseButton";Wu.propTypes=sv;const Jf=Wu,qf=y.forwardRef((e,t)=>{const{bsPrefix:n,show:r=!0,closeLabel:l="Close alert",closeVariant:o,className:i,children:u,variant:s="primary",onClose:a,dismissible:h,transition:p=Kl,...d}=yh(e,{show:"onClose"}),S=H(n,"alert"),g=Fe(m=>{a&&a(!1,m)}),x=p===!0?Kl:p,R=f.jsxs("div",{role:"alert",...x?void 0:d,ref:t,className:M(i,S,s&&`${S}-${s}`,h&&`${S}-dismissible`),children:[h&&f.jsx(Jf,{onClick:g,"aria-label":l,variant:o}),u]});return x?f.jsx(x,{unmountOnExit:!0,...d,ref:void 0,in:r,children:R}):r?R:null});qf.displayName="Alert";const fa=Object.assign(qf,{Link:iv,Heading:Kh}),bf=y.forwardRef(({as:e,bsPrefix:t,variant:n="primary",size:r,active:l=!1,disabled:o=!1,className:i,...u},s)=>{const a=H(t,"btn"),[h,{tagName:p}]=Hu({tagName:e,disabled:o,...u}),d=p;return f.jsx(d,{...h,...u,ref:s,disabled:o,className:M(i,a,l&&"active",n&&`${a}-${n}`,r&&`${a}-${r}`,u.href&&o&&"disabled")})});bf.displayName="Button";const tn=bf;function av(e){const t=y.useRef(e);return t.current=e,t}function ed(e){const t=av(e);y.useEffect(()=>()=>t.current(),[])}function cv(e,t){let n=0;return y.Children.map(e,r=>y.isValidElement(r)?t(r,n++):r)}function fv(e,t){return y.Children.toArray(e).some(n=>y.isValidElement(n)&&n.type===t)}function dv({as:e,bsPrefix:t,className:n,...r}){t=H(t,"col");const l=Df(),o=If(),i=[],u=[];return l.forEach(s=>{const a=r[s];delete r[s];let h,p,d;typeof a=="object"&&a!=null?{span:h,offset:p,order:d}=a:h=a;const S=s!==o?`-${s}`:"";h&&i.push(h===!0?`${t}${S}`:`${t}${S}-${h}`),d!=null&&u.push(`order${S}-${d}`),p!=null&&u.push(`offset${S}-${p}`)}),[{...r,className:M(n,...i,...u)},{as:e,bsPrefix:t,spans:i}]}const td=y.forwardRef((e,t)=>{const[{className:n,...r},{as:l="div",bsPrefix:o,spans:i}]=dv(e);return f.jsx(l,{...r,ref:t,className:M(n,!i.length&&o)})});td.displayName="Col";const Vu=td,nd=y.forwardRef(({bsPrefix:e,fluid:t=!1,as:n="div",className:r,...l},o)=>{const i=H(e,"container"),u=typeof t=="string"?`-${t}`:"-fluid";return f.jsx(n,{ref:o,...l,className:M(r,t?`${i}${u}`:i)})});nd.displayName="Container";const pv=nd;var mv=Function.prototype.bind.call(Function.prototype.call,[].slice);function dn(e,t){return mv(e.querySelectorAll(t))}function da(e,t){if(e.contains)return e.contains(t);if(e.compareDocumentPosition)return e===t||!!(e.compareDocumentPosition(t)&16)}const hv="data-rr-ui-";function vv(e){return`${hv}${e}`}const rd=y.createContext(Vn?window:void 0);rd.Provider;function Qu(){return y.useContext(rd)}const yv={type:it.string,tooltip:it.bool,as:it.elementType},Ku=y.forwardRef(({as:e="div",className:t,type:n="valid",tooltip:r=!1,...l},o)=>f.jsx(e,{...l,ref:o,className:M(t,`${n}-${r?"tooltip":"feedback"}`)}));Ku.displayName="Feedback";Ku.propTypes=yv;const ld=Ku,gv=y.createContext({}),ft=gv,od=y.forwardRef(({id:e,bsPrefix:t,className:n,type:r="checkbox",isValid:l=!1,isInvalid:o=!1,as:i="input",...u},s)=>{const{controlId:a}=y.useContext(ft);return t=H(t,"form-check-input"),f.jsx(i,{...u,ref:s,type:r,id:e||a,className:M(n,t,l&&"is-valid",o&&"is-invalid")})});od.displayName="FormCheckInput";const id=od,ud=y.forwardRef(({bsPrefix:e,className:t,htmlFor:n,...r},l)=>{const{controlId:o}=y.useContext(ft);return e=H(e,"form-check-label"),f.jsx("label",{...r,ref:l,htmlFor:n||o,className:M(t,e)})});ud.displayName="FormCheckLabel";const Gi=ud,sd=y.forwardRef(({id:e,bsPrefix:t,bsSwitchPrefix:n,inline:r=!1,reverse:l=!1,disabled:o=!1,isValid:i=!1,isInvalid:u=!1,feedbackTooltip:s=!1,feedback:a,feedbackType:h,className:p,style:d,title:S="",type:g="checkbox",label:x,children:R,as:m="input",...c},v)=>{t=H(t,"form-check"),n=H(n,"form-switch");const{controlId:w}=y.useContext(ft),E=y.useMemo(()=>({controlId:e||w}),[w,e]),T=!R&&x!=null&&x!==!1||fv(R,Gi),N=f.jsx(id,{...c,type:g==="switch"?"checkbox":g,ref:v,isValid:i,isInvalid:u,disabled:o,as:m});return f.jsx(ft.Provider,{value:E,children:f.jsx("div",{style:d,className:M(p,T&&t,r&&`${t}-inline`,l&&`${t}-reverse`,g==="switch"&&n),children:R||f.jsxs(f.Fragment,{children:[N,T&&f.jsx(Gi,{title:S,children:x}),a&&f.jsx(ld,{type:h,tooltip:s,children:a})]})})})});sd.displayName="FormCheck";const Gl=Object.assign(sd,{Input:id,Label:Gi}),ad=y.forwardRef(({bsPrefix:e,type:t,size:n,htmlSize:r,id:l,className:o,isValid:i=!1,isInvalid:u=!1,plaintext:s,readOnly:a,as:h="input",...p},d)=>{const{controlId:S}=y.useContext(ft);return e=H(e,"form-control"),f.jsx(h,{...p,type:t,size:r,ref:d,readOnly:a,id:l||S,className:M(o,s?`${e}-plaintext`:e,n&&`${e}-${n}`,t==="color"&&`${e}-color`,i&&"is-valid",u&&"is-invalid")})});ad.displayName="FormControl";const wv=Object.assign(ad,{Feedback:ld}),cd=y.forwardRef(({className:e,bsPrefix:t,as:n="div",...r},l)=>(t=H(t,"form-floating"),f.jsx(n,{ref:l,className:M(e,t),...r})));cd.displayName="FormFloating";const Sv=cd,fd=y.forwardRef(({controlId:e,as:t="div",...n},r)=>{const l=y.useMemo(()=>({controlId:e}),[e]);return f.jsx(ft.Provider,{value:l,children:f.jsx(t,{...n,ref:r})})});fd.displayName="FormGroup";const dd=fd,pd=y.forwardRef(({as:e="label",bsPrefix:t,column:n=!1,visuallyHidden:r=!1,className:l,htmlFor:o,...i},u)=>{const{controlId:s}=y.useContext(ft);t=H(t,"form-label");let a="col-form-label";typeof n=="string"&&(a=`${a} ${a}-${n}`);const h=M(l,t,r&&"visually-hidden",n&&a);return o=o||s,n?f.jsx(Vu,{ref:u,as:"label",className:h,htmlFor:o,...i}):f.jsx(e,{ref:u,className:h,htmlFor:o,...i})});pd.displayName="FormLabel";const xv=pd,md=y.forwardRef(({bsPrefix:e,className:t,id:n,...r},l)=>{const{controlId:o}=y.useContext(ft);return e=H(e,"form-range"),f.jsx("input",{...r,type:"range",ref:l,className:M(t,e),id:n||o})});md.displayName="FormRange";const kv=md,hd=y.forwardRef(({bsPrefix:e,size:t,htmlSize:n,className:r,isValid:l=!1,isInvalid:o=!1,id:i,...u},s)=>{const{controlId:a}=y.useContext(ft);return e=H(e,"form-select"),f.jsx("select",{...u,size:n,ref:s,className:M(r,e,t&&`${e}-${t}`,l&&"is-valid",o&&"is-invalid"),id:i||a})});hd.displayName="FormSelect";const Ev=hd,vd=y.forwardRef(({bsPrefix:e,className:t,as:n="small",muted:r,...l},o)=>(e=H(e,"form-text"),f.jsx(n,{...l,ref:o,className:M(t,e,r&&"text-muted")})));vd.displayName="FormText";const Cv=vd,yd=y.forwardRef((e,t)=>f.jsx(Gl,{...e,ref:t,type:"switch"}));yd.displayName="Switch";const Tv=Object.assign(yd,{Input:Gl.Input,Label:Gl.Label}),gd=y.forwardRef(({bsPrefix:e,className:t,children:n,controlId:r,label:l,...o},i)=>(e=H(e,"form-floating"),f.jsxs(dd,{ref:i,className:M(t,e),controlId:r,...o,children:[n,f.jsx("label",{htmlFor:r,children:l})]})));gd.displayName="FloatingLabel";const Nv=gd,_v={_ref:it.any,validated:it.bool,as:it.elementType},Gu=y.forwardRef(({className:e,validated:t,as:n="form",...r},l)=>f.jsx(n,{...r,ref:l,className:M(e,t&&"was-validated")}));Gu.displayName="Form";Gu.propTypes=_v;const Me=Object.assign(Gu,{Group:dd,Control:wv,Floating:Sv,Check:Gl,Switch:Tv,Label:xv,Text:Cv,Range:kv,Select:Ev,FloatingLabel:Nv});var ul;function pa(e){if((!ul&&ul!==0||e)&&Vn){var t=document.createElement("div");t.style.position="absolute",t.style.top="-9999px",t.style.width="50px",t.style.height="50px",t.style.overflow="scroll",document.body.appendChild(t),ul=t.offsetWidth-t.clientWidth,document.body.removeChild(t)}return ul}function Wo(e){e===void 0&&(e=po());try{var t=e.activeElement;return!t||!t.nodeName?null:t}catch{return e.body}}function jv(e=document){const t=e.defaultView;return Math.abs(t.innerWidth-e.documentElement.clientWidth)}const ma=vv("modal-open");class Rv{constructor({ownerDocument:t,handleContainerOverflow:n=!0,isRTL:r=!1}={}){this.handleContainerOverflow=n,this.isRTL=r,this.modals=[],this.ownerDocument=t}getScrollbarWidth(){return jv(this.ownerDocument)}getElement(){return(this.ownerDocument||document).body}setModalAttributes(t){}removeModalAttributes(t){}setContainerStyle(t){const n={overflow:"hidden"},r=this.isRTL?"paddingLeft":"paddingRight",l=this.getElement();t.style={overflow:l.style.overflow,[r]:l.style[r]},t.scrollBarWidth&&(n[r]=`${parseInt(Xt(l,r)||"0",10)+t.scrollBarWidth}px`),l.setAttribute(ma,""),Xt(l,n)}reset(){[...this.modals].forEach(t=>this.remove(t))}removeContainerStyle(t){const n=this.getElement();n.removeAttribute(ma),Object.assign(n.style,t.style)}add(t){let n=this.modals.indexOf(t);return n!==-1||(n=this.modals.length,this.modals.push(t),this.setModalAttributes(t),n!==0)||(this.state={scrollBarWidth:this.getScrollbarWidth(),style:{}},this.handleContainerOverflow&&this.setContainerStyle(this.state)),n}remove(t){const n=this.modals.indexOf(t);n!==-1&&(this.modals.splice(n,1),!this.modals.length&&this.handleContainerOverflow&&this.removeContainerStyle(this.state),this.removeModalAttributes(t))}isTopModal(t){return!!this.modals.length&&this.modals[this.modals.length-1]===t}}const Yu=Rv,Vo=(e,t)=>Vn?e==null?(t||po()).body:(typeof e=="function"&&(e=e()),e&&"current"in e&&(e=e.current),e&&("nodeType"in e||e.getBoundingClientRect)?e:null):null;function Lv(e,t){const n=Qu(),[r,l]=y.useState(()=>Vo(e,n==null?void 0:n.document));if(!r){const o=Vo(e);o&&l(o)}return y.useEffect(()=>{t&&r&&t(r)},[t,r]),y.useEffect(()=>{const o=Vo(e);o!==r&&l(o)},[e,r]),r}function Pv({children:e,in:t,onExited:n,mountOnEnter:r,unmountOnExit:l}){const o=y.useRef(null),i=y.useRef(t),u=Fe(n);y.useEffect(()=>{t?i.current=!0:u(o.current)},[t,u]);const s=mo(o,e.ref),a=y.cloneElement(e,{ref:s});return t?a:l||!i.current&&r?null:a}function Ov({in:e,onTransition:t}){const n=y.useRef(null),r=y.useRef(!0),l=Fe(t);return ca(()=>{if(!n.current)return;let o=!1;return l({in:e,element:n.current,initial:r.current,isStale:()=>o}),()=>{o=!0}},[e,l]),ca(()=>(r.current=!1,()=>{r.current=!0}),[]),n}function Fv({children:e,in:t,onExited:n,onEntered:r,transition:l}){const[o,i]=y.useState(!t);t&&o&&i(!1);const u=Ov({in:!!t,onTransition:a=>{const h=()=>{a.isStale()||(a.in?r==null||r(a.element,a.initial):(i(!0),n==null||n(a.element)))};Promise.resolve(l(a)).then(h,p=>{throw a.in||i(!0),p})}}),s=mo(u,e.ref);return o&&!t?null:y.cloneElement(e,{ref:s})}function ha(e,t,n){return e?f.jsx(e,Object.assign({},n)):t?f.jsx(Fv,Object.assign({},n,{transition:t})):f.jsx(Pv,Object.assign({},n))}function Mv(e){return e.code==="Escape"||e.keyCode===27}const zv=["show","role","className","style","children","backdrop","keyboard","onBackdropClick","onEscapeKeyDown","transition","runTransition","backdropTransition","runBackdropTransition","autoFocus","enforceFocus","restoreFocus","restoreFocusOptions","renderDialog","renderBackdrop","manager","container","onShow","onHide","onExit","onExited","onExiting","onEnter","onEntering","onEntered"];function $v(e,t){if(e==null)return{};var n={},r=Object.keys(e),l,o;for(o=0;o=0)&&(n[l]=e[l]);return n}let Qo;function Dv(e){return Qo||(Qo=new Yu({ownerDocument:e==null?void 0:e.document})),Qo}function Iv(e){const t=Qu(),n=e||Dv(t),r=y.useRef({dialog:null,backdrop:null});return Object.assign(r.current,{add:()=>n.add(r.current),remove:()=>n.remove(r.current),isTopModal:()=>n.isTopModal(r.current),setDialogRef:y.useCallback(l=>{r.current.dialog=l},[]),setBackdropRef:y.useCallback(l=>{r.current.backdrop=l},[])})}const wd=y.forwardRef((e,t)=>{let{show:n=!1,role:r="dialog",className:l,style:o,children:i,backdrop:u=!0,keyboard:s=!0,onBackdropClick:a,onEscapeKeyDown:h,transition:p,runTransition:d,backdropTransition:S,runBackdropTransition:g,autoFocus:x=!0,enforceFocus:R=!0,restoreFocus:m=!0,restoreFocusOptions:c,renderDialog:v,renderBackdrop:w=K=>f.jsx("div",Object.assign({},K)),manager:E,container:T,onShow:N,onHide:j=()=>{},onExit:U,onExited:O,onExiting:ie,onEnter:Ke,onEntering:Ge,onEntered:on}=e,Qn=$v(e,zv);const je=Qu(),Ye=Lv(T),C=Iv(E),L=Yh(),P=Xh(n),[D,A]=y.useState(!n),fe=y.useRef(null);y.useImperativeHandle(t,()=>C,[C]),Vn&&!P&&n&&(fe.current=Wo(je==null?void 0:je.document)),n&&D&&A(!1);const Re=Fe(()=>{if(C.add(),sn.current=Ql(document,"keydown",ho),un.current=Ql(document,"focus",()=>setTimeout(Le),!0),N&&N(),x){var K,Hr;const Yn=Wo((K=(Hr=C.dialog)==null?void 0:Hr.ownerDocument)!=null?K:je==null?void 0:je.document);C.dialog&&Yn&&!da(C.dialog,Yn)&&(fe.current=Yn,C.dialog.focus())}}),et=Fe(()=>{if(C.remove(),sn.current==null||sn.current(),un.current==null||un.current(),m){var K;(K=fe.current)==null||K.focus==null||K.focus(c),fe.current=null}});y.useEffect(()=>{!n||!Ye||Re()},[n,Ye,Re]),y.useEffect(()=>{D&&et()},[D,et]),ed(()=>{et()});const Le=Fe(()=>{if(!R||!L()||!C.isTopModal())return;const K=Wo(je==null?void 0:je.document);C.dialog&&K&&!da(C.dialog,K)&&C.dialog.focus()}),mt=Fe(K=>{K.target===K.currentTarget&&(a==null||a(K),u===!0&&j())}),ho=Fe(K=>{s&&Mv(K)&&C.isTopModal()&&(h==null||h(K),K.defaultPrevented||j())}),un=y.useRef(),sn=y.useRef(),Kn=(...K)=>{A(!0),O==null||O(...K)};if(!Ye)return null;const Br=Object.assign({role:r,ref:C.setDialogRef,"aria-modal":r==="dialog"?!0:void 0},Qn,{style:o,className:l,tabIndex:-1});let Gn=v?v(Br):f.jsx("div",Object.assign({},Br,{children:y.cloneElement(i,{role:"document"})}));Gn=ha(p,d,{unmountOnExit:!0,mountOnEnter:!0,appear:!0,in:!!n,onExit:U,onExiting:ie,onExited:Kn,onEnter:Ke,onEntering:Ge,onEntered:on,children:Gn});let It=null;return u&&(It=w({ref:C.setBackdropRef,onClick:mt}),It=ha(S,g,{in:!!n,appear:!0,mountOnEnter:!0,unmountOnExit:!0,children:It})),f.jsx(f.Fragment,{children:Nn.createPortal(f.jsxs(f.Fragment,{children:[It,Gn]}),Ye)})});wd.displayName="Modal";const Av=Object.assign(wd,{Manager:Yu});function Uv(e,t){return e.classList?!!t&&e.classList.contains(t):(" "+(e.className.baseVal||e.className)+" ").indexOf(" "+t+" ")!==-1}function Bv(e,t){e.classList?e.classList.add(t):Uv(e,t)||(typeof e.className=="string"?e.className=e.className+" "+t:e.setAttribute("class",(e.className&&e.className.baseVal||"")+" "+t))}function va(e,t){return e.replace(new RegExp("(^|\\s)"+t+"(?:\\s|$)","g"),"$1").replace(/\s+/g," ").replace(/^\s*|\s*$/g,"")}function Hv(e,t){e.classList?e.classList.remove(t):typeof e.className=="string"?e.className=va(e.className,t):e.setAttribute("class",va(e.className&&e.className.baseVal||"",t))}const pn={FIXED_CONTENT:".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",STICKY_CONTENT:".sticky-top",NAVBAR_TOGGLER:".navbar-toggler"};class Wv extends Yu{adjustAndStore(t,n,r){const l=n.style[t];n.dataset[t]=l,Xt(n,{[t]:`${parseFloat(Xt(n,t))+r}px`})}restore(t,n){const r=n.dataset[t];r!==void 0&&(delete n.dataset[t],Xt(n,{[t]:r}))}setContainerStyle(t){super.setContainerStyle(t);const n=this.getElement();if(Bv(n,"modal-open"),!t.scrollBarWidth)return;const r=this.isRTL?"paddingLeft":"paddingRight",l=this.isRTL?"marginLeft":"marginRight";dn(n,pn.FIXED_CONTENT).forEach(o=>this.adjustAndStore(r,o,t.scrollBarWidth)),dn(n,pn.STICKY_CONTENT).forEach(o=>this.adjustAndStore(l,o,-t.scrollBarWidth)),dn(n,pn.NAVBAR_TOGGLER).forEach(o=>this.adjustAndStore(l,o,t.scrollBarWidth))}removeContainerStyle(t){super.removeContainerStyle(t);const n=this.getElement();Hv(n,"modal-open");const r=this.isRTL?"paddingLeft":"paddingRight",l=this.isRTL?"marginLeft":"marginRight";dn(n,pn.FIXED_CONTENT).forEach(o=>this.restore(r,o)),dn(n,pn.STICKY_CONTENT).forEach(o=>this.restore(l,o)),dn(n,pn.NAVBAR_TOGGLER).forEach(o=>this.restore(l,o))}}let Ko;function Vv(e){return Ko||(Ko=new Wv(e)),Ko}const Sd=y.forwardRef(({className:e,bsPrefix:t,as:n="div",...r},l)=>(t=H(t,"modal-body"),f.jsx(n,{ref:l,className:M(e,t),...r})));Sd.displayName="ModalBody";const Qv=Sd,Kv=y.createContext({onHide(){}}),xd=Kv,kd=y.forwardRef(({bsPrefix:e,className:t,contentClassName:n,centered:r,size:l,fullscreen:o,children:i,scrollable:u,...s},a)=>{e=H(e,"modal");const h=`${e}-dialog`,p=typeof o=="string"?`${e}-fullscreen-${o}`:`${e}-fullscreen`;return f.jsx("div",{...s,ref:a,className:M(h,t,l&&`${e}-${l}`,r&&`${h}-centered`,u&&`${h}-scrollable`,o&&p),children:f.jsx("div",{className:M(`${e}-content`,n),children:i})})});kd.displayName="ModalDialog";const Ed=kd,Cd=y.forwardRef(({className:e,bsPrefix:t,as:n="div",...r},l)=>(t=H(t,"modal-footer"),f.jsx(n,{ref:l,className:M(e,t),...r})));Cd.displayName="ModalFooter";const Gv=Cd,Yv=y.forwardRef(({closeLabel:e="Close",closeVariant:t,closeButton:n=!1,onHide:r,children:l,...o},i)=>{const u=y.useContext(xd),s=Fe(()=>{u==null||u.onHide(),r==null||r()});return f.jsxs("div",{ref:i,...o,children:[l,n&&f.jsx(Jf,{"aria-label":e,variant:t,onClick:s})]})}),Xv=Yv,Td=y.forwardRef(({bsPrefix:e,className:t,closeLabel:n="Close",closeButton:r=!1,...l},o)=>(e=H(e,"modal-header"),f.jsx(Xv,{ref:o,...l,className:M(t,e),closeLabel:n,closeButton:r})));Td.displayName="ModalHeader";const Zv=Td,Jv=Qf("h4"),Nd=y.forwardRef(({className:e,bsPrefix:t,as:n=Jv,...r},l)=>(t=H(t,"modal-title"),f.jsx(n,{ref:l,className:M(e,t),...r})));Nd.displayName="ModalTitle";const qv=Nd;function bv(e){return f.jsx(Kl,{...e,timeout:null})}function ey(e){return f.jsx(Kl,{...e,timeout:null})}const _d=y.forwardRef(({bsPrefix:e,className:t,style:n,dialogClassName:r,contentClassName:l,children:o,dialogAs:i=Ed,"aria-labelledby":u,"aria-describedby":s,"aria-label":a,show:h=!1,animation:p=!0,backdrop:d=!0,keyboard:S=!0,onEscapeKeyDown:g,onShow:x,onHide:R,container:m,autoFocus:c=!0,enforceFocus:v=!0,restoreFocus:w=!0,restoreFocusOptions:E,onEntered:T,onExit:N,onExiting:j,onEnter:U,onEntering:O,onExited:ie,backdropClassName:Ke,manager:Ge,...on},Qn)=>{const[je,Ye]=y.useState({}),[C,L]=y.useState(!1),P=y.useRef(!1),D=y.useRef(!1),A=y.useRef(null),[fe,Re]=Gh(),et=mo(Qn,Re),Le=Fe(R),mt=xh();e=H(e,"modal");const ho=y.useMemo(()=>({onHide:Le}),[Le]);function un(){return Ge||Vv({isRTL:mt})}function sn($){if(!Vn)return;const an=un().getScrollbarWidth()>0,Zu=$.scrollHeight>po($).documentElement.clientHeight;Ye({paddingRight:an&&!Zu?pa():void 0,paddingLeft:!an&&Zu?pa():void 0})}const Kn=Fe(()=>{fe&&sn(fe.dialog)});ed(()=>{Ki(window,"resize",Kn),A.current==null||A.current()});const Br=()=>{P.current=!0},Gn=$=>{P.current&&fe&&$.target===fe.dialog&&(D.current=!0),P.current=!1},It=()=>{L(!0),A.current=Vf(fe.dialog,()=>{L(!1)})},K=$=>{$.target===$.currentTarget&&It()},Hr=$=>{if(d==="static"){K($);return}if(D.current||$.target!==$.currentTarget){D.current=!1;return}R==null||R()},Yn=$=>{S?g==null||g($):($.preventDefault(),d==="static"&&It())},Dd=($,an)=>{$&&sn($),U==null||U($,an)},Id=$=>{A.current==null||A.current(),N==null||N($)},Ad=($,an)=>{O==null||O($,an),Wf(window,"resize",Kn)},Ud=$=>{$&&($.style.display=""),ie==null||ie($),Ki(window,"resize",Kn)},Bd=y.useCallback($=>f.jsx("div",{...$,className:M(`${e}-backdrop`,Ke,!p&&"show")}),[p,Ke,e]),Xu={...n,...je};Xu.display="block";const Hd=$=>f.jsx("div",{role:"dialog",...$,style:Xu,className:M(t,e,C&&`${e}-static`,!p&&"show"),onClick:d?Hr:void 0,onMouseUp:Gn,"aria-label":a,"aria-labelledby":u,"aria-describedby":s,children:f.jsx(i,{...on,onMouseDown:Br,className:r,contentClassName:l,children:o})});return f.jsx(xd.Provider,{value:ho,children:f.jsx(Av,{show:h,ref:et,backdrop:d,container:m,keyboard:!0,autoFocus:c,enforceFocus:v,restoreFocus:w,restoreFocusOptions:E,onEscapeKeyDown:Yn,onShow:x,onHide:R,onEnter:Dd,onEntering:Ad,onEntered:T,onExit:Id,onExiting:j,onExited:Ud,manager:un(),transition:p?bv:void 0,backdropTransition:p?ey:void 0,renderBackdrop:Bd,renderDialog:Hd})})});_d.displayName="Modal";const ye=Object.assign(_d,{Body:Qv,Header:Zv,Title:qv,Footer:Gv,Dialog:Ed,TRANSITION_DURATION:300,BACKDROP_TRANSITION_DURATION:150}),ya=1e3;function ty(e,t,n){const r=(e-t)/(n-t)*100;return Math.round(r*ya)/ya}function ga({min:e,now:t,max:n,label:r,visuallyHidden:l,striped:o,animated:i,className:u,style:s,variant:a,bsPrefix:h,...p},d){return f.jsx("div",{ref:d,...p,role:"progressbar",className:M(u,`${h}-bar`,{[`bg-${a}`]:a,[`${h}-bar-animated`]:i,[`${h}-bar-striped`]:i||o}),style:{width:`${ty(t,e,n)}%`,...s},"aria-valuenow":t,"aria-valuemin":e,"aria-valuemax":n,children:l?f.jsx("span",{className:"visually-hidden",children:r}):r})}const jd=y.forwardRef(({isChild:e=!1,...t},n)=>{const r={min:0,max:100,animated:!1,visuallyHidden:!1,striped:!1,...t};if(r.bsPrefix=H(r.bsPrefix,"progress"),e)return ga(r,n);const{min:l,now:o,max:i,label:u,visuallyHidden:s,striped:a,animated:h,bsPrefix:p,variant:d,className:S,children:g,...x}=r;return f.jsx("div",{ref:n,...x,className:M(S,p),children:g?cv(g,R=>y.cloneElement(R,{isChild:!0})):ga({min:l,now:o,max:i,label:u,visuallyHidden:s,striped:a,animated:h,bsPrefix:p,variant:d},n)})});jd.displayName="ProgressBar";const ny=jd,Rd=y.forwardRef(({bsPrefix:e,className:t,as:n="div",...r},l)=>{const o=H(e,"row"),i=Df(),u=If(),s=`${o}-cols`,a=[];return i.forEach(h=>{const p=r[h];delete r[h];let d;p!=null&&typeof p=="object"?{cols:d}=p:d=p;const S=h!==u?`-${h}`:"";d!=null&&a.push(`${s}${S}-${d}`)}),f.jsx(n,{ref:l,...r,className:M(t,o,...a)})});Rd.displayName="Row";const Ld=Rd,Pd=y.forwardRef(({bsPrefix:e,variant:t,animation:n="border",size:r,as:l="div",className:o,...i},u)=>{e=H(e,"spinner");const s=`${e}-${n}`;return f.jsx(l,{ref:u,...i,className:M(o,s,r&&`${s}-${r}`,t&&`text-${t}`)})});Pd.displayName="Spinner";const Un=Pd,Sl="initializing",wa="paused",Od="live",ry="error",ln=y.createContext({listTorrents:()=>{throw new Error("Function not implemented.")},getTorrentDetails:()=>{throw new Error("Function not implemented.")},getTorrentStats:()=>{throw new Error("Function not implemented.")},uploadTorrent:()=>{throw new Error("Function not implemented.")},pause:()=>{throw new Error("Function not implemented.")},start:()=>{throw new Error("Function not implemented.")},forget:()=>{throw new Error("Function not implemented.")},delete:()=>{throw new Error("Function not implemented.")}}),Ur=y.createContext({setCloseableError:e=>{},refreshTorrents:()=>{}}),Fd=y.createContext({refresh:()=>{}}),Go=({className:e,onClick:t,disabled:n,color:r})=>{const l=o=>{o.stopPropagation(),!n&&t()};return f.jsx("a",{className:`bi ${e} p-1`,onClick:l,href:"#"})},ly=({id:e,show:t,onHide:n})=>{if(!t)return null;const[r,l]=y.useState(!1),[o,i]=y.useState(null),[u,s]=y.useState(!1),a=y.useContext(Ur),h=y.useContext(ln),p=()=>{l(!1),i(null),s(!1),n()},d=()=>{s(!0),(r?h.delete:h.forget)(e).then(()=>{a.refreshTorrents(),p()}).catch(g=>{i({text:`Error deleting torrent id=${e}`,details:g}),s(!1)})};return f.jsxs(ye,{show:t,onHide:p,children:[f.jsx(ye.Header,{closeButton:!0,children:"Delete torrent"}),f.jsxs(ye.Body,{children:[f.jsx(Me,{children:f.jsx(Me.Group,{controlId:"delete-torrent",children:f.jsx(Me.Check,{type:"checkbox",label:"Also delete files",checked:r,onChange:()=>l(!r)})})}),o&&f.jsx(Mr,{error:o})]}),f.jsxs(ye.Footer,{children:[u&&f.jsx(Un,{}),f.jsx(tn,{variant:"primary",onClick:d,disabled:u,children:"OK"}),f.jsx(tn,{variant:"secondary",onClick:p,children:"Cancel"})]})]})},oy=({id:e,statsResponse:t})=>{let n=t.state,[r,l]=y.useState(!1),[o,i]=y.useState(!1),u=y.useContext(Fd);const s=n=="live",a=n=="paused"||n=="error",h=y.useContext(Ur),p=y.useContext(ln),d=()=>{l(!0),p.start(e).then(()=>{u.refresh()},R=>{h.setCloseableError({text:`Error starting torrent id=${e}`,details:R})}).finally(()=>l(!1))},S=()=>{l(!0),p.pause(e).then(()=>{u.refresh()},R=>{h.setCloseableError({text:`Error pausing torrent id=${e}`,details:R})}).finally(()=>l(!1))},g=()=>{l(!0),i(!0)},x=()=>{l(!1),i(!1)};return f.jsx(Ld,{children:f.jsxs(Vu,{children:[a&&f.jsx(Go,{className:"bi-play-circle",onClick:d,disabled:r,color:"success"}),s&&f.jsx(Go,{className:"bi-pause-circle",onClick:S,disabled:r}),f.jsx(Go,{className:"bi-x-circle",onClick:g,disabled:r,color:"danger"}),f.jsx(ly,{id:e,show:o,onHide:x})]})})},iy=({id:e,detailsResponse:t,statsResponse:n})=>{const r=(n==null?void 0:n.state)??"",l=n==null?void 0:n.error,o=(n==null?void 0:n.total_bytes)??1,i=(n==null?void 0:n.progress_bytes)??0,u=(n==null?void 0:n.finished)||!1,s=l?100:i/o*100,a=(r==Sl||r==Od)&&!u,h=l?"Error":`${s.toFixed(2)}%`,p=l?"danger":u?"success":r==Sl?"warning":"primary",d=()=>{var R;let x=(R=n==null?void 0:n.live)==null?void 0:R.snapshot.peer_stats;return x?`${x.live} / ${x.seen}`:""},S=()=>{var x;if(u)return"Completed";switch(r){case wa:return"Paused";case Sl:return"Checking files";case ry:return"Error"}return((x=n==null?void 0:n.live)==null?void 0:x.download_speed.human_readable)??"N/A"};let g=[];return l?g.push("bg-warning"):e%2==0&&g.push("bg-light"),f.jsxs(Ld,{className:g.join(" "),children:[f.jsx(vt,{size:3,label:"Name",children:t?f.jsxs(f.Fragment,{children:[f.jsx("div",{className:"text-truncate",children:yy(t)}),l&&f.jsxs("p",{className:"text-danger",children:[f.jsx("strong",{children:"Error:"})," ",l]})]}):f.jsx(Un,{})}),n?f.jsxs(f.Fragment,{children:[f.jsx(vt,{label:"Size",children:`${zd(o)} `}),f.jsx(vt,{size:2,label:(r==wa,"Progress"),children:f.jsx(ny,{now:s,label:h,animated:a,variant:p})}),f.jsx(vt,{size:2,label:"Down Speed",children:S()}),f.jsx(vt,{label:"ETA",children:gy(n)}),f.jsx(vt,{size:2,label:"Peers",children:d()}),f.jsx(vt,{label:"Actions",children:f.jsx(oy,{id:e,statsResponse:n})})]}):f.jsx(vt,{label:"Loading stats",size:8,children:f.jsx(Un,{})})]})},vt=({size:e,label:t,children:n})=>f.jsxs(Vu,{md:e||1,className:"py-3",children:[f.jsx("div",{className:"fw-bold",children:t}),n]}),uy=({id:e,torrent:t})=>{const[n,r]=y.useState(null),[l,o]=y.useState(null),[i,u]=y.useState(0),s=y.useContext(ln),a=()=>{u(i+1)};return y.useEffect(()=>{if(n===null)return Sy(async()=>{await s.getTorrentDetails(t.id).then(r)},1e3)},[n]),y.useEffect(()=>$d(async()=>s.getTorrentStats(t.id).then(g=>(o(g),g)).then(g=>g.finished?1e4:g.state==Sl||g.state==Od?1e3:1e4,()=>1e4),0),[i]),f.jsx(Fd.Provider,{value:{refresh:a},children:f.jsx(iy,{id:e,detailsResponse:n,statsResponse:l})})},sy=e=>{if(e.torrents===null&&e.loading)return f.jsx(Un,{});if(e.torrents!==null)return e.torrents.length===0?f.jsx("div",{className:"text-center",children:f.jsx("p",{children:"No existing torrents found. Add them through buttons below."})}):f.jsx(f.Fragment,{children:e.torrents.map(t=>f.jsx(uy,{id:t.id,torrent:t},t.id))})},ay=()=>{const[e,t]=y.useState(null),[n,r]=y.useState(null),[l,o]=y.useState(null),[i,u]=y.useState(!1),s=y.useContext(ln),a=async()=>{u(!0);let p=await s.listTorrents().finally(()=>u(!1));o(p.torrents)};y.useEffect(()=>$d(async()=>a().then(()=>(r(null),5e3),p=>(r({text:"Error refreshing torrents",details:p}),console.error(p),5e3)),0),[]);const h={setCloseableError:t,refreshTorrents:a};return f.jsx(Ur.Provider,{value:h,children:f.jsxs("div",{className:"text-center",children:[f.jsx("h1",{className:"mt-3 mb-4",children:"rqbit web 4.0.0-beta.0"}),f.jsx(vy,{closeableError:e,otherError:n,torrents:l,torrentsLoading:i})]})})},cy=e=>{let{details:t}=e;return t?f.jsxs(f.Fragment,{children:[f.jsx("p",{children:t.status&&f.jsxs("strong",{children:[t.status," ",t.statusText]})}),f.jsx("pre",{children:t.text})]}):null},Mr=e=>{let{error:t,remove:n}=e;return t==null?null:f.jsxs(fa,{variant:"danger",onClose:n,dismissible:n!=null,children:[f.jsx(fa.Heading,{children:t.text}),f.jsx(cy,{details:t.details})]})},Md=({buttonText:e,onClick:t,data:n,resetData:r,variant:l})=>{const[o,i]=y.useState(!1),[u,s]=y.useState(null),[a,h]=y.useState(null),p=y.useContext(ln);y.useEffect(()=>{if(n===null)return;let S=setTimeout(async()=>{i(!0);try{const g=await p.uploadTorrent(n,{list_only:!0});s(g)}catch(g){h({text:"Error listing torrent files",details:g})}finally{i(!1)}},0);return()=>clearTimeout(S)},[n]);const d=()=>{r(),h(null),s(null),i(!1)};return f.jsxs(f.Fragment,{children:[f.jsx(tn,{variant:l,onClick:t,className:"m-1",children:e}),n&&f.jsx(my,{onHide:d,listTorrentError:a,listTorrentResponse:u,data:n,listTorrentLoading:o})]})},fy=({show:e,setUrl:t,cancel:n})=>{let[r,l]=y.useState("");return f.jsxs(ye,{show:e,onHide:n,size:"lg",children:[f.jsx(ye.Header,{closeButton:!0,children:f.jsx(ye.Title,{children:"Add torrent"})}),f.jsx(ye.Body,{children:f.jsx(Me,{children:f.jsxs(Me.Group,{className:"mb-3",controlId:"url",children:[f.jsx(Me.Label,{children:"Enter magnet or HTTP(S) URL to the .torrent"}),f.jsx(Me.Control,{value:r,placeholder:"magnet:?xt=urn:btih:...",onChange:o=>{l(o.target.value)}})]})})}),f.jsxs(ye.Footer,{children:[f.jsx(tn,{variant:"primary",onClick:()=>{t(r),l("")},disabled:r.length==0,children:"OK"}),f.jsx(tn,{variant:"secondary",onClick:n,children:"Cancel"})]})]})},dy=()=>{let[e,t]=y.useState(null),[n,r]=y.useState(!1);return f.jsxs(f.Fragment,{children:[f.jsx(Md,{variant:"primary",buttonText:"Add Torrent from Magnet / URL",onClick:()=>{r(!0)},data:e,resetData:()=>t(null)}),f.jsx(fy,{show:n,setUrl:l=>{r(!1),t(l)},cancel:()=>{r(!1),t(null)}})]})},py=()=>{const e=y.useRef(),[t,n]=y.useState(null),r=async()=>{var u;if(!((u=e==null?void 0:e.current)!=null&&u.files))return;const i=e.current.files[0];n(i)},l=()=>{e!=null&&e.current&&(e.current.value="",n(null))},o=()=>{e!=null&&e.current&&e.current.click()};return f.jsxs(f.Fragment,{children:[f.jsx("input",{type:"file",ref:e,accept:".torrent",onChange:r,className:"d-none"}),f.jsx(Md,{variant:"secondary",buttonText:"Upload .torrent File",onClick:o,data:t,resetData:l})]})},my=e=>{let{onHide:t,listTorrentResponse:n,listTorrentError:r,listTorrentLoading:l,data:o}=e;const[i,u]=y.useState([]),[s,a]=y.useState(!1),[h,p]=y.useState(null),[d,S]=y.useState(!1),g=y.useContext(Ur),x=y.useContext(ln);y.useEffect(()=>{u(n?n.details.files.map((w,E)=>E):[])},[n]);const R=()=>{t(),u([]),p(null),a(!1)},m=w=>{i.includes(w)?u(i.filter(E=>E!==w)):u([...i,w])},c=async()=>{if(!n)return;a(!0);let w=n.seen_peers?n.seen_peers.slice(0,32):null,E={overwrite:!0,only_files:i,initial_peers:w};d&&(E.peer_opts={connect_timeout:20,read_write_timeout:60}),x.uploadTorrent(o,E).then(()=>{t(),g.refreshTorrents()},T=>{p({text:"Error starting torrent",details:T})}).finally(()=>a(!1))},v=()=>{if(l)return f.jsx(Un,{});if(r)return f.jsx(Mr,{error:r});if(n)return f.jsxs(Me,{children:[f.jsxs("fieldset",{className:"mb-5",children:[f.jsx("legend",{children:"Pick the files to download"}),n.details.files.map((w,E)=>f.jsx(Me.Group,{controlId:`check-${E}`,children:f.jsx(Me.Check,{type:"checkbox",label:`${w.name} (${zd(w.length)})`,checked:i.includes(E),onChange:()=>m(E)})},E))]}),f.jsxs("fieldset",{children:[f.jsx("legend",{children:"Other options"}),f.jsxs(Me.Group,{controlId:"unpopular-torrent",children:[f.jsx(Me.Check,{type:"checkbox",label:"Increase timeouts",checked:d,onChange:()=>S(!d)}),f.jsx("small",{id:"emailHelp",className:"form-text text-muted",children:"This might be useful for unpopular torrents with few peers. It will slow down fast torrents though."})]})]})]})};return f.jsxs(ye,{show:!0,onHide:R,size:"lg",children:[f.jsx(ye.Header,{closeButton:!0,children:f.jsx(ye.Title,{children:"Add torrent"})}),f.jsxs(ye.Body,{children:[v(),f.jsx(Mr,{error:h})]}),f.jsxs(ye.Footer,{children:[s&&f.jsx(Un,{}),f.jsx(tn,{variant:"primary",onClick:c,disabled:l||s||i.length==0,children:"OK"}),f.jsx(tn,{variant:"secondary",onClick:R,children:"Cancel"})]})]})},hy=()=>f.jsxs("div",{id:"buttons-container",className:"mt-3",children:[f.jsx(dy,{}),f.jsx(py,{})]}),vy=e=>{let t=y.useContext(Ur);return f.jsxs(pv,{children:[f.jsx(Mr,{error:e.closeableError,remove:()=>t.setCloseableError(null)}),f.jsx(Mr,{error:e.otherError}),f.jsx(sy,{torrents:e.torrents,loading:e.torrentsLoading}),f.jsx(hy,{})]})};function zd(e){if(e===0)return"0 Bytes";const t=1024,n=["Bytes","KB","MB","GB"],r=Math.floor(Math.log(e)/Math.log(t));return parseFloat((e/Math.pow(t,r)).toFixed(2))+" "+n[r]}function yy(e){return e.files.filter(n=>n.included).reduce((n,r)=>n.length>r.length?n:r).name}function gy(e){var n,r,l;let t=(l=(r=(n=e==null?void 0:e.live)==null?void 0:n.time_remaining)==null?void 0:r.duration)==null?void 0:l.secs;return t==null?"N/A":wy(t)}function wy(e){const t=Math.floor(e/3600),n=Math.floor(e%3600/60),r=e%60,l=(o,i)=>o>0?`${o}${i}`:"";return t>0?`${l(t,"h")} ${l(n,"m")}`.trim():n>0?`${l(n,"m")} ${l(r,"s")}`.trim():`${l(r,"s")}`.trim()}function $d(e,t){let n,r=t;const l=async()=>{if(r=await e(),r==null)throw"asyncCallback returned null or undefined";o()};let o=()=>{n=setTimeout(l,r)};return o(),()=>{clearTimeout(n)}}function Sy(e,t){let n;const r=async()=>{await e().then(()=>!1,()=>!0)&&l()};let l=o=>{n=setTimeout(r,o!==void 0?o:t)};return l(0),()=>clearTimeout(n)}const xy=window.origin==="null"||window.origin==="http://localhost:3031"?"http://localhost:3030":"",yt=async(e,t,n)=>{console.log(e,t);const r=xy+t,l={method:e,headers:{Accept:"application/json"},body:n};let o={method:e,path:t,text:""},i;try{i=await fetch(r,l)}catch{return o.text="network error",Promise.reject(o)}if(o.status=i.status,o.statusText=i.statusText,!i.ok){const s=await i.text();try{const a=JSON.parse(s);o.text=a.human_readable!==void 0?a.human_readable:JSON.stringify(a,null,2)}catch{o.text=s}return Promise.reject(o)}return await i.json()},ky={listTorrents:()=>yt("GET","/torrents"),getTorrentDetails:e=>yt("GET",`/torrents/${e}`),getTorrentStats:e=>yt("GET",`/torrents/${e}/stats/v1`),uploadTorrent:(e,t)=>{var r,l;let n="/torrents?&overwrite=true";return t!=null&&t.list_only&&(n+="&list_only=true"),(t==null?void 0:t.only_files)!=null&&(n+=`&only_files=${t.only_files.join(",")}`),(r=t==null?void 0:t.peer_opts)!=null&&r.connect_timeout&&(n+=`&peer_connect_timeout=${t.peer_opts.connect_timeout}`),(l=t==null?void 0:t.peer_opts)!=null&&l.read_write_timeout&&(n+=`&peer_read_write_timeout=${t.peer_opts.read_write_timeout}`),t!=null&&t.initial_peers&&(n+=`&initial_peers=${t.initial_peers.join(",")}`),typeof e=="string"&&(n+="&is_url=true"),yt("POST",n,e)},pause:e=>yt("POST",`/torrents/${e}/pause`),start:e=>yt("POST",`/torrents/${e}/start`),forget:e=>yt("POST",`/torrents/${e}/forget`),delete:e=>yt("POST",`/torrents/${e}/delete`)};Yo.createRoot(document.getElementById("app")).render(f.jsx(y.StrictMode,{children:f.jsx(ln.Provider,{value:ky,children:f.jsx(ay,{})})})); diff --git a/crates/librqbit/webui/dist/manifest.json b/crates/librqbit/webui/dist/manifest.json index c5e3d91..544e31c 100644 --- a/crates/librqbit/webui/dist/manifest.json +++ b/crates/librqbit/webui/dist/manifest.json @@ -4,7 +4,7 @@ "src": "assets/logo.svg" }, "index.html": { - "file": "assets/index-c6a3908d.js", + "file": "assets/index-386e9e08.js", "isEntry": true, "src": "index.html" } diff --git a/crates/librqbit/webui/src/api-types.ts b/crates/librqbit/webui/src/api-types.ts index f7b6293..4ab0de9 100644 --- a/crates/librqbit/webui/src/api-types.ts +++ b/crates/librqbit/webui/src/api-types.ts @@ -26,19 +26,6 @@ export interface ListTorrentsResponse { torrents: Array; } -export interface TorrentAddQueryParams { - overwrite?: boolean | null; - output_folder?: string | null; - sub_folder?: string | null; - only_files_regex?: string | null; - only_files?: string, - peer_connect_timeout?: number | null; - peer_read_write_timeout?: number | null; - initial_peers?: string | null; - is_url?: boolean | null; - list_only?: boolean | null; -} - // Interface for the Torrent Stats API response export interface LiveTorrentStats { snapshot: { diff --git a/crates/librqbit/webui/src/rqbit-web.tsx b/crates/librqbit/webui/src/rqbit-web.tsx index f10df2f..ec7c953 100644 --- a/crates/librqbit/webui/src/rqbit-web.tsx +++ b/crates/librqbit/webui/src/rqbit-web.tsx @@ -1,6 +1,6 @@ import { MouseEventHandler, RefObject, createContext, useContext, useEffect, useRef, useState } from 'react'; import { ProgressBar, Button, Container, Row, Col, Alert, Modal, Form, Spinner } from 'react-bootstrap'; -import { AddTorrentResponse, TorrentDetails, TorrentId, TorrentStats, ErrorDetails as ApiErrorDetails, STATE_INITIALIZING, STATE_LIVE, STATE_PAUSED, STATE_ERROR, RqbitAPI, ErrorDetails, ListTorrentsResponse, AddTorrentOptions } from './api-types'; +import { AddTorrentResponse, TorrentDetails, TorrentId, TorrentStats, ErrorDetails as ApiErrorDetails, STATE_INITIALIZING, STATE_LIVE, STATE_PAUSED, STATE_ERROR, RqbitAPI, AddTorrentOptions } from './api-types'; interface Error { text: string, @@ -318,7 +318,7 @@ const Torrent: React.FC<{ return liveInterval; } return nonLiveInterval; - }, (e) => { + }, () => { return errorInterval; }); }), 0), [forceStatsRefresh]); @@ -442,7 +442,7 @@ const UploadButton: React.FC<{ const response = await API.uploadTorrent(data, { list_only: true }); setListTorrentResponse(response); } catch (e) { - setListTorrentError({ text: 'Error listing torrent files', details: e as ErrorDetails }); + setListTorrentError({ text: 'Error listing torrent files', details: e as ApiErrorDetails }); } finally { setLoading(false); } @@ -511,11 +511,6 @@ const MagnetInput = () => { let [showModal, setShowModal] = useState(false); - const onClick = () => { - const m = prompt('Enter magnet link or HTTP(s) URL'); - setMagnet(m === '' ? null : m); - }; - return ( <>