diff --git a/web/public_html/transmission-app.js b/web/public_html/transmission-app.js index 79005153c4..5f6167b9cf 100644 --- a/web/public_html/transmission-app.js +++ b/web/public_html/transmission-app.js @@ -1,4 +1,4 @@ -(()=>{var ve=Object.create;var Ce=Object.defineProperty;var Xe=Object.getOwnPropertyDescriptor;var Ze=Object.getOwnPropertyNames;var Fe=Object.getPrototypeOf,Le=Object.prototype.hasOwnProperty;var we=(n,e)=>()=>(e||n((e={exports:{}}).exports,e),e.exports);var We=(n,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Ze(e))!Le.call(n,r)&&r!==t&&Ce(n,r,{get:()=>e[r],enumerable:!(o=Xe(e,r))||o.enumerable});return n};var Qe=(n,e,t)=>(t=n!=null?ve(Fe(n)):{},We(e||!n||!n.__esModule?Ce(t,"default",{value:n,enumerable:!0}):t,n));var fe=we((je,Ae)=>{"use strict";Ae.exports=function n(e,t){if(e===t)return!0;if(e&&t&&typeof e=="object"&&typeof t=="object"){if(e.constructor!==t.constructor)return!1;var o,r,s;if(Array.isArray(e)){if(o=e.length,o!=t.length)return!1;for(r=o;r--!==0;)if(!n(e[r],t[r]))return!1;return!0}if(e instanceof Map&&t instanceof Map){if(e.size!==t.size)return!1;for(r of e.entries())if(!t.has(r[0]))return!1;for(r of e.entries())if(!n(r[1],t.get(r[0])))return!1;return!0}if(e instanceof Set&&t instanceof Set){if(e.size!==t.size)return!1;for(r of e.entries())if(!t.has(r[0]))return!1;return!0}if(ArrayBuffer.isView(e)&&ArrayBuffer.isView(t)){if(o=e.length,o!=t.length)return!1;for(r=o;r--!==0;)if(e[r]!==t[r])return!1;return!0}if(e.constructor===RegExp)return e.source===t.source&&e.flags===t.flags;if(e.valueOf!==Object.prototype.valueOf)return e.valueOf()===t.valueOf();if(e.toString!==Object.prototype.toString)return e.toString()===t.toString();if(s=Object.keys(e),o=s.length,o!==Object.keys(t).length)return!1;for(r=o;r--!==0;)if(!Object.prototype.hasOwnProperty.call(t,s[r]))return!1;for(r=o;r--!==0;){var i=s[r];if(!n(e[i],t[i]))return!1}return!0}return e!==e&&t!==t}});var j=class n extends EventTarget{constructor(){super(),this.actions=Object.seal({"copy-name":{enabled:!0,text:"Copy name"},"deselect-all":{enabled:!1,shortcut:"D",text:"Deselect all"},"move-bottom":{enabled:!1,text:"Bottom"},"move-down":{enabled:!1,text:"Down"},"move-top":{enabled:!1,text:"Top"},"move-up":{enabled:!1,text:"Up"},"open-torrent":{enabled:!0,shortcut:"O",text:"Open torrent\u2026"},"pause-all-torrents":{enabled:!1,text:"Pause all"},"pause-selected-torrents":{enabled:!1,shortcut:"U",text:"Pause"},"reannounce-selected-torrents":{enabled:!1,text:"Ask tracker for more peers"},"remove-selected-torrents":{enabled:!1,text:"Remove selected torrents"},"resume-selected-torrents":{enabled:!1,shortcut:"R",text:"Resume"},"resume-selected-torrents-now":{enabled:!1,text:"Resume now"},"select-all":{enabled:!1,shortcut:"A",text:"Select all"},"show-about-dialog":{enabled:!0,text:"About"},"show-inspector":{enabled:!1,shortcut:"I",text:"Torrent Inspector"},"show-labels-dialog":{enabled:!1,shortcut:"K",text:"Edit Labels\u2026"},"show-move-dialog":{enabled:!1,shortcut:"L",text:"Set location\u2026"},"show-overflow-menu":{enabled:!0,text:"More options\u2026"},"show-preferences-dialog":{enabled:!0,shortcut:"P",text:"Edit preferences"},"show-rename-dialog":{enabled:!1,shortcut:"N",text:"Rename\u2026"},"show-shortcuts-dialog":{enabled:!0,text:"Keyboard shortcuts"},"show-statistics-dialog":{enabled:!0,shortcut:"S",text:"Statistics"},"start-all-torrents":{enabled:!1,text:"Start all"},"toggle-compact-rows":{enabled:!0,text:"Compact rows"},"toggle-contrast":{enabled:!0,text:"High contrast UI"},"verify-selected-torrents":{enabled:!1,shortcut:"V",text:"Verify local data"}})}click(e){if(this.isEnabled(e)){let t=new Event("click");t.action=e,this.dispatchEvent(t)}}getActionForShortcut(e){for(let[t,o]of Object.entries(this.actions))if(e===o.shortcut)return t;return null}allShortcuts(){return new Map(Object.entries(this.actions).filter(([,e])=>e.shortcut).map(([e,t])=>[t.shortcut,e]))}isEnabled(e){return this._getAction(e).enabled}text(e){return this._getAction(e).text}keyshortcuts(e){return this._getAction(e).shortcut}update(e){let t=n._recount(e.selected,e.nonselected);this._updateStates(t)}_getAction(e){let t=this.actions[e];if(!t)throw new Error(`no such action: ${e}`);return t}static _recount(e,t){let o=e.length+t.length,r=e.filter(d=>d.isStopped()).length,s=e.length-r,i=t.filter(d=>d.isStopped()).length,a=t.length-i,c=r+i,l=s+a,u=e.filter(d=>d.isQueued()).length;return{active:l,nonselected_active:a,nonselected_paused:i,paused:c,selected:e.length,selected_active:s,selected_paused:r,selected_queued:u,total:o}}_updateStates(e){let t=(o,r)=>{for(let s of r)this._updateActionState(s,o)};t(e.selected_paused>0,["resume-selected-torrents"]),t(e.paused>0,["start-all-torrents"]),t(e.active>0,["pause-all-torrents"]),t(e.selected_paused>0||e.selected_queued>0,["resume-selected-torrents-now"]),t(e.selected_active>0,["pause-selected-torrents","reannounce-selected-torrents"]),t(e.selected>0,["deselect-all","move-bottom","move-down","move-top","move-up","remove-selected-torrents","show-inspector","show-labels-dialog","show-move-dialog","verify-selected-torrents"]),t(e.selected===1,["show-rename-dialog"]),t(e.selectedUe(r,d,i,l,t))}return a[0].classList.add("selected"),i.children[0].classList.remove("hidden"),{buttons:a,dismiss:s,root:o}}function X(n){let e=document.createElement("dialog");e.classList.add("dialog-container","popup",n),e.open=!0,e.setAttribute("role","dialog");let t=document.createElement("div");t.classList.add("dialog-window"),e.append(t);let o=document.createElement("div");o.classList.add("dialog-logo"),t.append(o);let r=document.createElement("div");r.classList.add("dialog-heading"),t.append(r);let s=document.createElement("div");s.classList.add("dialog-message"),t.append(s);let i=document.createElement("div");i.classList.add("dialog-workarea"),t.append(i);let a=document.createElement("div");a.classList.add("dialog-buttons"),t.append(a);let c=document.createElement("span");c.className="flexible-space",a.append(c);let l=document.createElement("button");l.classList.add("dialog-dismiss-button"),l.textContent="Cancel",a.append(l);let u=document.createElement("button");return u.textContent="OK",a.append(u),t.addEventListener("keyup",({key:d})=>{d==="Enter"&&u.click()}),{confirm:u,dismiss:l,heading:r,message:s,root:e,workarea:i}}function v(){return typeof crypto.randomUUID=="function"?crypto.randomUUID():("10000000-1000-4000-8000"+-1e11).replaceAll(/[018]/g,n=>(n^crypto.getRandomValues(new Uint8Array(1))[0]&15>>n/4).toString(16))}function S(n,e,t){let o=t.map(r=>new Option(...r));if(e){let r=document.createElement("OPTGROUP");r.label=e,r.append(...o),n.append(r)}else n.append(...o)}var K=Object.freeze({delete:()=>R(["path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2L21 6L3 6"}],["line",{x1:10,x2:10,y1:11,y2:17}],["line",{x1:14,x2:14,y1:11,y2:17}]),inspector:()=>{let n=N("svg",{fill:"none","fill-opacity":1,height:26,stroke:"currentColor",viewBox:"-1 -1 26 26",width:26}),e=N("g",{});return e.append(N("circle",{cx:12,cy:12,r:11,"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":2}),N("path",{d:"M 11.88208 4.883789 C 12.326418 4.883789 12.702391 5.039305 13.01001 5.350342 C 13.317628 5.6613785 13.471436 6.035642 13.471436 6.4731445 C 13.471436 6.910647 13.31592 7.283202 13.004883 7.59082 C 12.693846 7.898439 12.319582 8.052246 11.88208 8.052246 C 11.444578 8.052246 11.072023 7.898439 10.764404 7.59082 C 10.456786 7.283202 10.302979 6.910647 10.302979 6.4731445 C 10.302979 6.035642 10.456786 5.6613785 10.764404 5.350342 C 11.072023 5.039305 11.444578 4.883789 11.88208 4.883789 Z M 13.317627 9.528809 L 13.317627 17.126953 C 13.317627 17.803714 13.39624 18.236083 13.553467 18.424072 C 13.710694 18.612061 14.018308 18.719726 14.476318 18.74707 L 14.476318 19.11621 L 9.298096 19.11621 L 9.298096 18.74707 C 9.721926 18.733398 10.036376 18.610353 10.241455 18.37793 C 10.378175 18.220702 10.446533 17.803714 10.446533 17.126953 L 10.446533 11.52832 C 10.446533 10.851559 10.367921 10.41919 10.210693 10.231201 C 10.053466 10.043212 9.74927 9.935547 9.298096 9.908203 L 9.298096 9.528809 Z",fill:"currentColor"})),n.append(e),n},open:()=>R(["path",{d:"M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"}],["line",{x1:12,x2:12,y1:11,y2:17}],["line",{x1:9,x2:15,y1:14,y2:14}]),overflow:()=>R(["line",{x1:3,x2:21,y1:12,y2:12}],["line",{x1:3,x2:21,y1:6,y2:6}],["line",{x1:3,x2:21,y1:18,y2:18}]),pause:()=>R(["rect",{height:16,width:4,x:6,y:4}],["rect",{height:16,width:4,x:14,y:4}]),speedDown:()=>R(["polyline",{points:"6 9 12 15 18 9"}]),speedUp:()=>R(["polyline",{points:"18 15 12 9 6 15"}]),start:()=>R(["polyline",{points:"5 3 19 12 5 21 5 3"}])});function Oe(n){let e=document.createElement("fieldset");e.classList.add("section");let t=document.createElement("legend");t.classList.add("title"),t.textContent=n,e.append(t);let o=document.createElement("div");return o.classList.add("content"),e.append(o),{content:o,root:e}}function be(n,e){let t=[],{root:o,content:r}=Oe(n);for(let s of e){let i=document.createElement("label");i.textContent=s,r.append(i);let a=document.createElement("div");a.id=v(),r.append(a),i.setAttribute("for",a.id),t.push(a)}return{children:t,root:o}}function Y(n,e=100){let t=null;return(...o)=>{t||(t=setTimeout(()=>{t=null,n(...o)},e))}}function P(n,e){return(0,Be.default)(n,e)}function Te(n,e,t){t?n.setAttribute(e,!0):n.removeAttribute(e)}function L(n,e){Te(n,"disabled",!e)}function $(n,e){n.classList.toggle("checked",e)}var T=class extends EventTarget{constructor(e){super(),this.listener=t=>{e.contains(t.target)||(this.dispatchEvent(new MouseEvent(t.type,t)),t.preventDefault())},Object.seal(this),this.start()}start(){setTimeout(()=>document.addEventListener("click",this.listener),0)}stop(){document.removeEventListener("click",this.listener)}};function b(n,e){n.textContent!==e&&(n.textContent=e)}var q=class{constructor(e){this._prefs=e,this._elements={toggle:document.querySelector("#toggle-notifications")}}_setEnabled(e){this.prefs.notifications_enabled=e,b(this._toggle,`${e?"Disable":"Enable"} Notifications`)}_requestPermission(){Notification.requestPermission().then(e=>this._setEnabled(e==="granted"))}toggle(){this._enabled?this._setEnabled(!1):Notification.permission==="granted"?this._setEnabled(!0):Notification.permission!=="denied"&&this._requestPermission()}};var p=class n extends EventTarget{constructor(){super(),this._cache={},this.dispatchPrefsChange=Y((e,t,o)=>{let r=new Event("change");Object.assign(r,{key:e,old_value:t,value:o}),this.dispatchEvent(r)});for(let[e,t]of Object.entries(n._Defaults))this._set(e,n._getCookie(e,t)),Object.defineProperty(this,e.replaceAll("-","_"),{get:()=>this._get(e),set:o=>{this._set(e,o)}});Object.seal(this)}entries(){return Object.entries(this._cache)}keys(){return Object.keys(this._cache)}_get(e){let{_cache:t}=this;if(!Object.prototype.hasOwnProperty.call(t,e))throw new Error(e);return t[e]}_set(e,t){let{_cache:o}=this,r=o[e];r!==t&&(o[e]=t,n._setCookie(e,t),this.dispatchPrefsChange(e,r,t))}static _setCookie(e,t){let o=new Date;o.setFullYear(o.getFullYear()+1),document.cookie=`${e}=${t}; SameSite=Strict; expires=${o.toGMTString()}`}static _getCookie(e,t){let o=n._readCookie(e);if(o===null)return t;let r=typeof t;if(r==="boolean")return o==="true"?!0:o==="false"?!1:t;if(r==="number"){let s=Number.parseFloat(o);return Number.isNaN(s)?t:s}return o}static _readCookie(e){let o=`; ${document.cookie}`.split(`; ${e}=`);return o.length===2?o.pop().split(";").shift():null}};p.AltSpeedEnabled="alt-speed-enabled";p.DisplayCompact="compact";p.DisplayFull="full";p.DisplayMode="display-mode";p.ContrastLess="less";p.ContrastMore="more";p.ContrastMode="contrast-mode";p.FilterActive="active";p.FilterAll="all";p.FilterDownloading="downloading";p.FilterError="error";p.FilterFinished="finished";p.FilterMode="filter-mode";p.FilterPaused="paused";p.FilterPrivate="private";p.FilterPublic="public";p.FilterSeeding="seeding";p.NotificationsEnabled="notifications-enabled";p.RefreshRate="refresh-rate-sec";p.SortAscending="ascending";p.SortByActivity="activity";p.SortByAge="age";p.SortByName="name";p.SortByProgress="progress";p.SortByQueue="queue";p.SortByRatio="ratio";p.SortBySize="size";p.SortByState="state";p.SortDescending="descending";p.SortDirection="sort-direction";p.SortMode="sort-mode";p._Defaults={[p.AltSpeedEnabled]:!1,[p.DisplayMode]:p.DisplayFull,[p.ContrastMode]:globalThis.matchMedia("(prefers-contrast: more)").matches?p.ContrastMore:p.ContrastLess,[p.FilterMode]:p.FilterAll,[p.NotificationsEnabled]:!1,[p.RefreshRate]:5,[p.SortDirection]:p.SortAscending,[p.SortMode]:p.SortByName};var ee=class n extends EventTarget{constructor(e){super(),this.elements=n._create(e),this.elements.dismiss.addEventListener("click",()=>this.close()),document.body.append(this.elements.root),this.elements.dismiss.focus()}close(){this.elements.root.remove(),this.dispatchEvent(new Event("close")),delete this.elements}static _create(e){let t=X("about-dialog");t.root.setAttribute("aria-label","About transmission"),t.heading.textContent="Transmission",t.dismiss.textContent="Close";let o=document.createElement("div");return o.classList.add("about-dialog-version-number"),o.textContent=e.version,t.heading.append(o),o=document.createElement("div"),o.classList.add("about-dialog-version-checksum"),o.textContent=e.checksum,t.heading.append(o),o=document.createElement("div"),o.textContent="A fast and easy bitTorrent client",t.workarea.append(o),o=document.createElement("div"),o.textContent="Copyright \xA9 The Transmission Project",t.workarea.append(o),o=document.createElement("a"),o.href="https://transmissionbt.com/",o.target="_blank",o.textContent="https://transmissionbt.com/",t.workarea.append(o),t.confirm.remove(),delete t.confirm,t}};var te=class extends EventTarget{constructor(e,t){super(),this.action_listener=this._update.bind(this),this.controller=e,this.action_manager=e.action_manager,this.action_manager.addEventListener("change",this.action_listener),this.handler=e.handler,this.menu_items=t,Object.assign(this,this._create()),this.outside=new T(this.root),this.outside.addEventListener("click",()=>{this.handler&&this.handler.classList.remove("selected"),this.close()}),this.show()}show(){for(let[e,t]of Object.entries(this.actions))L(t,this.action_manager.isEnabled(e));document.body.append(this.root)}close(){if(!this.closed){this.outside.stop(),this.action_manager.removeEventListener("change",this.action_listener),this.root.remove(),this.dispatchEvent(new Event("close"));for(let e of Object.keys(this))delete this[e];this.closed=!0}}_update(e){let t=this.actions[e.action];t&&L(t,e.enabled)}_create(){let e=document.createElement("div");e.role="menu",e.classList.add("context-menu","popup"),e.addEventListener("contextmenu",i=>{i.preventDefault()}),e.style.pointerEvents="none";let t={},o=(i,a=!1)=>{let c=document.createElement("div"),l=this.action_manager.text(i);c.role="menuitem",a?c.classList.add("context-menuitem","warning"):c.classList.add("context-menuitem"),c.dataset.action=i,c.textContent=l;let u=this.action_manager.keyshortcuts(i);return u&&c.setAttribute("aria-keyshortcuts",u),c.addEventListener("click",()=>{this.action_manager.click(i),this.close()}),t[i]=c,c},r=()=>{let i=document.createElement("div");return i.classList.add("context-menu-separator"),i},s=(i,...a)=>{let c=document.createElement("div");c.className="context-menuitem",c.textContent=i;let l=document.createElement("div");l.className="arrow",c.append(l);let u=document.createElement("div");u.className="submenu",l.append(u);let d=document.createElement("div");return d.className="open right",u.append(d),d.append(...a.map(g=>o(g))),c.addEventListener("click",g=>{let m=c.lastChild.lastChild;if(!g.target.classList.contains("right")&&!g.target.parentNode.classList.contains("right")&&!g.target.classList.contains("left")&&!g.target.parentNode.classList.contains("left")&&m.style.display==="block"){m.style.display="none";return}for(let h of e.querySelectorAll(".submenu"))h.style.display="none";m.style.display="block";let I=c.getBoundingClientRect(),G=m.lastChild.getBoundingClientRect(),f=Math.min(0,document.documentElement.clientHeight-window.visualViewport.offsetTop-I.top-m.clientHeight+3),C=Math.min(0,document.documentElement.clientWidth-window.visualViewport.offsetLeft-I.right-m.clientWidth);m.style.top=`${f}px`,C?(m.lastChild.className="open left",m.style.left=`${-I.width-G.width}px`):(m.lastChild.className="open right",m.style.left=`${C}px`)}),c};if(this.menu_items)for(let i of this.menu_items)e.append(i?o(i):r());else e.append(o("resume-selected-torrents"),o("resume-selected-torrents-now"),o("pause-selected-torrents"),r(),s("Move in the queue","move-top","move-up","move-down","move-bottom"),r(),o("remove-selected-torrents",!0),r(),o("verify-selected-torrents"),o("show-move-dialog"),o("show-rename-dialog"),o("show-labels-dialog"),r(),o("reannounce-selected-torrents"),r(),s("Select operation","select-all","deselect-all"));return{actions:t,root:e}}};var ye=new Intl.PluralRules,W=ye.resolvedOptions().locale,Re=new Intl.NumberFormat(W),Ie=1e3,Ye=[new Intl.NumberFormat(W,{maximumFractionDigits:0,style:"unit",unit:"byte"}),new Intl.NumberFormat(W,{maximumFractionDigits:0,style:"unit",unit:"kilobyte"}),new Intl.NumberFormat(W,{maximumFractionDigits:0,style:"unit",unit:"megabyte"}),new Intl.NumberFormat(W,{maximumFractionDigits:2,style:"unit",unit:"gigabyte"}),new Intl.NumberFormat(W,{maximumFractionDigits:2,style:"unit",unit:"terabyte"}),new Intl.NumberFormat(W,{maximumFractionDigits:2,style:"unit",unit:"petabyte"})],Ne=new Intl.NumberFormat(W,{maximumFractionDigits:2,style:"unit",unit:"kilobyte-per-second"}),Se=new Intl.NumberFormat(W,{maximumFractionDigits:2,style:"unit",unit:"megabyte-per-second"}),Ve=new Intl.NumberFormat(W,{maximumFractionDigits:2,style:"unit",unit:"gigabyte-per-second"}),x={_toTruncFixed(n,e){return(Math.floor(n*10**e)/10**e).toFixed(e)},countString(n,e,t){return`${this.number(t)} ${this.ngettext(n,e,t)}`},mem(n){if(n<0)return"Unknown";if(n===0)return"None";let e=n;for(let t of Ye){if(en.includes(e))?"\u2026":n},timeInterval(n,e=3){let t=Math.floor(n/86400),o=[];t&&o.push(this.countString("day","days",t));let r=Math.floor(n%86400/3600);(t||r)&&o.push(this.countString("hour","hours",r));let s=Math.floor(n%3600/60);return t||r||s?(o.push(this.countString("minute","minutes",s)),o=o.slice(0,e),o.length>1?`${o.slice(0,-1).join(", ")} and ${o.slice(-1)}`:o[0]):this.countString("second","seconds",Math.floor(n%60))},timestamp(n){if(!n)return"N/A";let e=new Date(n*1e3),t=new Date,o="",r="",s=t.getFullYear()===e.getFullYear(),i=t.getMonth()===e.getMonth(),a=t.getDate()-e.getDate();s&&i&&Math.abs(a)<=1?a===0?o="Today":a===1?o="Yesterday":o="Tomorrow":o=e.toDateString();let c=e.getHours(),l="AM";c>12&&(c=c-12,l="PM"),c===0&&(c=12),c<10&&(c=`0${c}`);let u=e.getMinutes();return u<10&&(u=`0${u}`),n=e.getSeconds(),n<10&&(n=`0${n}`),r=[c,u,n].join(":"),[o,r,l].join(" ")},toKBps(n){return Math.floor(n/Ie)}};var oe=class extends EventTarget{isDone(){return this.fields.have>=this.fields.size}isEditable(){return this.fields.torrent.getFileCount()>1&&!this.isDone()}refreshWantedHTML(){let e=this.elements.root;e.classList.toggle("skip",!this.fields.isWanted),e.classList.toggle("complete",this.isDone()),L(e.checkbox,this.isEditable()),e.checkbox.checked=this.fields.isWanted}refreshProgressHTML(){let{size:e,have:t}=this.fields,o=100*(e?t/e:1),r=x,s=`${r.size(t)} of ${r.size(e)} (${r.percentString(o,1)}%)`;b(this.elements.progress,s)}refresh(){let e=0,t=!1,o=!1,r=!1,s=0,i=!1,a=this.fields.torrent.getFiles();for(let c of this.fields.indices){let l=a[c];switch(e+=l.bytesCompleted,s+=l.length,i|=l.wanted,l.priority.toString()){case"-1":o=!0;break;case"1":t=!0;break;default:r=!0;break}}$(this.elements.priority_low_button,o),$(this.elements.priority_normal_button,r),$(this.elements.priority_high_button,t),(this.fields.have!==e||this.fields.size!==s)&&(this.fields.have=e,this.fields.size=s,this.refreshProgressHTML()),this.fields.isWanted!==i&&(this.fields.isWanted=i,this.refreshWantedHTML())}fireWantedChanged(e){let t=new Event("wantedToggled");t.indices=[...this.fields.indices],t.wanted=e,this.dispatchEvent(t)}firePriorityChanged(e){let t=new Event("priorityToggled");t.indices=[...this.fields.indices],t.priority=e,this.dispatchEvent(t)}createRow(e,t){let o=document.createElement("li");o.classList.add("inspector-torrent-file-list-entry"),o.subtree=t,this.elements.root=o;let r=l=>{this.controller.handler&&this.controller.handler.classList.remove("selected"),setTimeout(()=>{o.classList.add("selected")},0);let u=t.name,d=t.parent;for(;d.name;){o.subdir=!0,u=`${d.name}/${u}`;let{parent:m}=d;d=m}o.file_path=u,this.controller.handler=o;let g=["show-rename-dialog",null,"copy-name"];this.controller.context_menu("#inspector",g),l.preventDefault()};this.controller.pointer_event(o,r);let s=document.createElement("input"),i=v();s.type="checkbox",s.className="file-wanted-control",s.title="Download file",s.id=i,s.addEventListener("change",l=>this.fireWantedChanged(l.target.checked)),o.checkbox=s,o.append(s),s=document.createElement("label"),s.className="inspector-torrent-file-list-entry-name",s.setAttribute("for",i),b(s,t.name),o.append(s),o.name_container=s,s=document.createElement("div"),s.className="inspector-torrent-file-list-entry-progress",o.append(s),this.elements.progress=s,s=document.createElement("div"),s.className="file-priority-radiobox";let a=s,c=l=>this.firePriorityChanged(l.target.value);s=document.createElement("input"),s.type="radio",s.value="-1",s.className="low",s.title="Low Priority",s.addEventListener("click",c),this.elements.priority_low_button=s,a.append(s),s=document.createElement("input"),s.type="radio",s.value="0",s.className="normal",s.title="Normal Priority",s.addEventListener("click",c),this.elements.priority_normal_button=s,a.append(s),s=document.createElement("input"),s.type="radio",s.value="1",s.title="High Priority",s.className="high",s.addEventListener("click",c),this.elements.priority_high_button=s,a.append(s),o.append(a),o.style.paddingLeft=`${t.depth*20}px`,this.refresh()}getElement(){return this.elements.root}constructor(e,t,o){super(),this.controller=e,this.fields={have:0,indices:o.file_indices,isWanted:!0,size:0,torrent:t},this.elements={priority_high_button:null,priority_low_button:null,priority_normal_button:null,progress:null,root:null},this.createRow(t,o)}};var A=class n extends EventTarget{constructor(e){super(),this.fieldObservers={},this.fields={},this.refresh(e),this.setLazyCollatedField("name","collatedName"),this.setLazyCollatedField("trackers","collatedTrackers")}setLazyCollatedField(e,t){this.notifyOnFieldChange(e,()=>delete this.fields[t])}notifyOnFieldChange(e,t){(this.fieldObservers[e]??=[]).push(t)}setField(e,t,o){let r=e[t];if(P(r,o))return!1;let s=this.fieldObservers[t];if(e===this.fields&&s&&s.length>0)for(let i of s)i.call(this,o,r,t);return e[t]=o,!0}updateFiles(e){let t=!1,o=this.fields.files||[],r=["length","name","bytesCompleted","wanted","priority"];for(let[s,i]of e.entries()){let a=o[s]||{};for(let c of r)c in i&&(t|=this.setField(a,c,i[c]));o[s]=a}return this.fields.files=o,t}static collateTrackers(e){return e.map(t=>t.announce.toLowerCase()).join(" ")}refreshFields(e){let t=!1;for(let[o,r]of Object.entries(e))switch(o){case"files":case"fileStats":t|=this.updateFiles(r);break;case"trackerStats":t|=this.setField(this.fields,"trackers",r);break;case"trackers":o in this.fields||(t|=this.setField(this.fields,o,r));break;default:t|=this.setField(this.fields,o,r)}return t}refresh(e){this.refreshFields(e)&&this.dispatchEvent(new Event("dataChanged"))}getIndividualFile(e){return this.fields.files.find(t=>t.name===e)}getComment(){return this.fields.comment}getCreator(){return this.fields.creator}getDateAdded(){return this.fields.addedDate}getDateCreated(){return this.fields.dateCreated}getDesiredAvailable(){return this.fields.desiredAvailable}getDownloadDir(){return this.fields.downloadDir}getDownloadSpeed(){return this.fields.rateDownload}getDownloadedEver(){return this.fields.downloadedEver}getError(){return this.fields.error}getErrorString(){return this.fields.errorString}getETA(){return this.fields.eta}getFailedEver(){return this.fields.corruptEver}getFiles(){return this.fields.files||[]}getFile(e){return this.fields.files[e]}getFileCount(){return this.fields["file-count"]}getHashString(){return this.fields.hashString}getHave(){return this.getHaveValid()+this.getHaveUnchecked()}getHaveUnchecked(){return this.fields.haveUnchecked}getHaveValid(){return this.fields.haveValid}getId(){return this.fields.id}getLabels(){return this.fields.labels.toSorted()}getLastActivity(){return this.fields.activityDate}getLeftUntilDone(){return this.fields.leftUntilDone}getMagnetLink(){return this.fields.magnetLink}getMetadataPercentComplete(){return this.fields.metadataPercentComplete}getName(){return this.fields.name||"Unknown"}getPeers(){return this.fields.peers||[]}getPeersConnected(){return this.fields.peersConnected}getPeersGettingFromUs(){return this.fields.peersGettingFromUs}getPeersSendingToUs(){return this.fields.peersSendingToUs}getPieceCount(){return this.fields.pieceCount}getPieceSize(){return this.fields.pieceSize}getPrimaryMimeType(){return this.fields["primary-mime-type"]||"application/octet-stream"}getPrivateFlag(){return this.fields.isPrivate}getQueuePosition(){return this.fields.queuePosition}getRecheckProgress(){return this.fields.recheckProgress}getSeedRatioLimit(){return this.fields.seedRatioLimit}getSeedRatioMode(){return this.fields.seedRatioMode}getSizeWhenDone(){return this.fields.sizeWhenDone}getStartDate(){return this.fields.startDate}getStatus(){return this.fields.status}getTotalSize(){return this.fields.totalSize}getTrackers(){return this.fields.trackers||[]}getUploadSpeed(){return this.fields.rateUpload}getUploadRatio(){return this.fields.uploadRatio}getUploadedEver(){return this.fields.uploadedEver}getWebseedsSendingToUs(){return this.fields.webseedsSendingToUs}isFinished(){return this.fields.isFinished}hasExtraInfo(){return"hashString"in this.fields}isSeeding(){return this.getStatus()===n._StatusSeed}isStopped(){return this.getStatus()===n._StatusStopped}isChecking(){return this.getStatus()===n._StatusCheck}isDownloading(){return this.getStatus()===n._StatusDownload}isQueued(){return this.getStatus()===n._StatusDownloadWait||this.getStatus()===n._StatusSeedWait}isDone(){return this.getLeftUntilDone()<1}needsMetaData(){return this.getMetadataPercentComplete()<1}getActivity(){return this.getDownloadSpeed()+this.getUploadSpeed()}getPercentDoneStr(){return x.percentString(100*this.getPercentDone(),1)}getPercentDone(){return this.fields.percentDone}getStateString(){switch(this.getStatus()){case n._StatusStopped:return this.isFinished()?"Seeding complete":"Paused";case n._StatusCheckWait:return"Queued for verification";case n._StatusCheck:return"Verifying local data";case n._StatusDownloadWait:return"Queued for download";case n._StatusDownload:return"Downloading";case n._StatusSeedWait:return"Queued for seeding";case n._StatusSeed:return"Seeding";case null:return"Unknown";default:return"Error"}}seedRatioLimit(e){switch(this.getSeedRatioMode()){case n._RatioUseGlobal:return e.seedRatioLimit();case n._RatioUseLocal:return this.getSeedRatioLimit();default:return-1}}getErrorMessage(){let e=this.getErrorString();switch(this.getError()){case n._ErrTrackerWarning:return`Tracker returned a warning: ${e}`;case n._ErrTrackerError:return`Tracker returned an error: ${e}`;case n._ErrLocalError:return`Error: ${e}`;default:return null}}getCollatedName(){let e=this.fields;return!e.collatedName&&e.name&&(e.collatedName=e.name.toLowerCase()),e.collatedName||""}getCollatedTrackers(){let e=this.fields;return!e.collatedTrackers&&e.trackers&&(e.collatedTrackers=n.collateTrackers(e.trackers)),e.collatedTrackers||""}testState(e){let t=this.getStatus();switch(e){case p.FilterError:return this.getError();case p.FilterPrivate:return this.getPrivateFlag();case p.FilterPublic:return!this.getPrivateFlag();case p.FilterActive:return this.getPeersGettingFromUs()>0||this.getPeersSendingToUs()>0||this.getWebseedsSendingToUs()>0||this.isChecking();case p.FilterSeeding:return t===n._StatusSeed||t===n._StatusSeedWait;case p.FilterDownloading:return t===n._StatusDownload||t===n._StatusDownloadWait;case p.FilterPaused:return this.isStopped();case p.FilterFinished:return this.isFinished();default:return!0}}test(e,t,o,r){let s=this.testState(e);if(s&&o&&(s=this.getCollatedName().includes(o.toLowerCase())),s){let i=this.getLabels();r.length>0&&(s=r.some(a=>i.includes(a)))}return s&&t&&t.length>0&&(s=this.getCollatedTrackers().includes(t)),s}static compareById(e,t){return e.getId()-t.getId()}static compareByName(e,t){return e.getCollatedName().localeCompare(t.getCollatedName())||n.compareById(e,t)}static compareByQueue(e,t){return e.getQueuePosition()-t.getQueuePosition()}static compareByAge(e,t){let o=e.getDateAdded();return t.getDateAdded()-o||n.compareByQueue(e,t)}static compareByState(e,t){let o=e.getStatus();return t.getStatus()-o||n.compareByQueue(e,t)}static compareByActivity(e,t){let o=e.getActivity();return t.getActivity()-o||n.compareByState(e,t)}static compareByRatio(e,t){let o=e.getUploadRatio(),r=t.getUploadRatio();return or?-1:n.compareByState(e,t)}static compareByProgress(e,t){let o=e.getPercentDone(),r=t.getPercentDone();return o-r||n.compareByRatio(e,t)}static compareBySize(e,t){let o=e.getTotalSize(),r=t.getTotalSize();return o-r||n.compareByName(e,t)}static compareTorrents(e,t,o,r){let s=0;switch(o){case p.SortByActivity:s=n.compareByActivity(e,t);break;case p.SortByAge:s=n.compareByAge(e,t);break;case p.SortByQueue:s=n.compareByQueue(e,t);break;case p.SortByProgress:s=n.compareByProgress(e,t);break;case p.SortBySize:s=n.compareBySize(e,t);break;case p.SortByState:s=n.compareByState(e,t);break;case p.SortByRatio:s=n.compareByRatio(e,t);break;case p.SortByName:s=n.compareByName(e,t);break;default:console.log(`Unrecognized sort mode: ${o}`),s=n.compareByName(e,t);break}return r===p.SortDescending&&(s=-s),s}static sortTorrents(e,t,o){switch(t){case p.SortByActivity:e.sort(this.compareByActivity);break;case p.SortByAge:e.sort(this.compareByAge);break;case p.SortByName:e.sort(this.compareByName);break;case p.SortByProgress:e.sort(this.compareByProgress);break;case p.SortByQueue:e.sort(this.compareByQueue);break;case p.SortByRatio:e.sort(this.compareByRatio);break;case p.SortBySize:e.sort(this.compareBySize);break;case p.SortByState:e.sort(this.compareByState);break;default:console.log(`Unrecognized sort mode: ${t}`),e.sort(this.compareByName);break}return o===p.SortDescending&&e.reverse(),e}};A._StatusStopped=0;A._StatusCheckWait=1;A._StatusCheck=2;A._StatusDownloadWait=3;A._StatusDownload=4;A._StatusSeedWait=5;A._StatusSeed=6;A._RatioUseGlobal=0;A._RatioUseLocal=1;A._RatioUnlimited=2;A._ErrNone=0;A._ErrTrackerWarning=1;A._ErrTrackerError=2;A._ErrLocalError=3;A._TrackerInactive=0;A._TrackerWaiting=1;A._TrackerQueued=2;A._TrackerActive=3;A.Fields={};A.Fields.Metadata=["addedDate","file-count","name","primary-mime-type","totalSize"];A.Fields.Stats=["error","errorString","eta","isFinished","isStalled","labels","leftUntilDone","metadataPercentComplete","peersConnected","peersGettingFromUs","peersSendingToUs","percentDone","queuePosition","rateDownload","rateUpload","recheckProgress","seedRatioMode","seedRatioLimit","sizeWhenDone","status","trackers","downloadDir","uploadedEver","uploadRatio","webseedsSendingToUs"];A.Fields.InfoExtra=["comment","creator","dateCreated","files","hashString","isPrivate","magnetLink","pieceCount","pieceSize"];A.Fields.StatsExtra=["activityDate","corruptEver","desiredAvailable","downloadedEver","fileStats","haveUnchecked","haveValid","peers","startDate","trackerStats"];var Ge=["encryption","speed-up","speed-down","percent-done","status","peer-address","peer-app-name"],E=class n extends EventTarget{constructor(e){super(),this.closed=!1,this.controller=e,this.elements=this._create(),this.current_page=this.elements.info.root,this.interval=setInterval(this._refreshTorrents.bind(this),3e3),this.name="inspector",this.selection_listener=t=>this._setTorrents(t.selected),this.torrent_listener=()=>this._updateCurrentPage(),this.torrents=[],this.file_torrent=null,this.file_torrent_n=null,this.file_rows=null,this.elements.dismiss.addEventListener("click",()=>this.close()),Object.seal(this),e.addEventListener("torrent-selection-changed",this.selection_listener),this._setTorrents(this.controller.getSelectedTorrents()),document.querySelector("#mainwin-workarea").append(this.elements.root)}close(){if(!this.closed){clearInterval(this.interval),this._setTorrents([]),this.elements.root.remove(),this.controller.removeEventListener("torrent-selection-changed",this.selection_listener),this.dispatchEvent(new Event("close"));for(let e of Object.keys(this))this[e]=null;this.closed=!0}}static _createInfoPage(){let e=document.createElement("div");e.classList.add("inspector-info-page");let t={root:e},o=i=>{let a=document.createElement("div");a.textContent=i,a.classList.add("section-label"),e.append(a)},r=i=>{let a=document.createElement("label");b(a,i),e.append(a);let c=document.createElement("span");return e.append(c),c};o("Activity");let s=[["have","Have:"],["availability","Availability:"],["uploaded","Uploaded:"],["downloaded","Downloaded:"],["state","State:"],["running_time","Running time:"],["remaining_time","Remaining:"],["last_activity","Last activity:"],["error","Error:"]];for(let[i,a]of s)t[i]=r(a);o("Details"),s=[["name","Name:"],["size","Size:"],["location","Location:"],["hash","Hash:"],["privacy","Privacy:"],["origin","Origin:"],["dateAdded","Date added:"],["magnetLink","Magnet:"],["comment","Comment:"],["labels","Labels:"]];for(let[i,a]of s)t[i]=r(a);return t}static _createListPage(e,t){let o=document.createElement("div"),r=document.createElement(e);return r.id=t,o.append(r),{list:r,root:o}}static _createTiersPage(){return n._createListPage("div","inspector-tiers-list")}static _createFilesPage(){return n._createListPage("ul","inspector-file-list")}static _createPeersPage(){let e=document.createElement("table");e.classList.add("peer-list");let t=document.createElement("thead"),o=document.createElement("tr"),r=["","Up","Down","Done","Status","Address","Client"];for(let[i,a]of r.entries()){let c=document.createElement("th"),l=Ge[i];l==="encryption"&&(c.dataset.encrypted=!0),c.classList.add(l),b(c,a),o.append(c)}let s=document.createElement("tbody");return t.append(o),e.append(t),e.append(s),{root:e,tbody:s}}_create(){let e={files:n._createFilesPage(),info:n._createInfoPage(),peers:n._createPeersPage(),tiers:n._createTiersPage()},t=r=>{this.current_page=r,this._updateCurrentPage()};return{...M("inspector",[["inspector-tab-info",e.info.root,"Info"],["inspector-tab-peers",e.peers.root,"Peers"],["inspector-tab-tiers",e.tiers.root,"Tiers"],["inspector-tab-files",e.files.root,"Files"]],t.bind(this)),...e}}_setTorrents(e){let t="dataChanged",o=this.torrent_listener;for(let r of this.torrents)r.removeEventListener(t,o);this.torrents=[...e];for(let r of this.torrents)r.addEventListener(t,o);this._refreshTorrents(),this._updateCurrentPage()}static _needsExtraInfo(e){return e.some(t=>!t.hasExtraInfo())}_refreshTorrents(){let{controller:e,torrents:t}=this,o=t.map(r=>r.getId());if(o&&o.length>0){let r=["id",...A.Fields.StatsExtra];n._needsExtraInfo(t)&&r.push(...A.Fields.InfoExtra),e.updateTorrents(o,r)}}_updateCurrentPage(){let{current_page:e,elements:t}=this;switch(e){case t.files.root:this._updateFiles();break;case t.info.root:this._updateInfo();break;case t.peers.root:this._updatePeers();break;case t.tiers.root:this._updateTiers();break;default:console.warn("unexpected page"),console.log(e)}}_updateInfo(){let e="None",t="Mixed",o="Unknown",r=x,s=Date.now(),{elements:i,torrents:a}=this,c=a.reduce((d,g)=>d+g.getSizeWhenDone(),0),l=null;if(a.length===0)l=e;else if(a.every(d=>d.isFinished()))l="Finished";else if(a.every(d=>d.isStopped()))l="Paused";else{let d=m=>m.getStateString(),g=d(a[0]);l=a.every(m=>d(m)===g)?g:t}b(i.info.state,l);let u=l;if(a.length===0)l=e;else{let d=a.reduce((G,f)=>G+f.getHaveValid(),0),g=a.reduce((G,f)=>G+f.getHaveUnchecked(),0),m=a.reduce((G,f)=>G+f.getLeftUntilDone(),0),I=100*(c?(c-m)/c:1);l=r.percentString(I,1),g?l=`${r.size(d)} of ${r.size(c)} (${l}%), ${r.size(g)} Unverified`:m?l=`${r.size(d)} of ${r.size(c)} (${l}%)`:l=`${r.size(d)} (100%)`}if(b(i.info.have,r.stringSanitizer(l)),a.length===0)l=e;else if(c===0)l=e;else{let d=a.reduce((g,m)=>m.getHave()+m.getDesiredAvailable(),0);l=`${r.percentString(100*d/c,1)}%`}if(b(i.info.availability,r.stringSanitizer(l)),a.length===0)l=e;else{let d=a.reduce((m,I)=>m+I.getDownloadedEver(),0),g=a.reduce((m,I)=>m+I.getFailedEver(),0);l=g?`${r.size(d)} (+${r.size(g)} discarded after failed checksum)`:r.size(d)}if(b(i.info.downloaded,r.stringSanitizer(l)),a.length===0)l=e;else{let d=a.reduce((m,I)=>m+I.getUploadedEver(),0),g=a.reduce((m,I)=>m+I.getSizeWhenDone(),0)||a.reduce((m,I)=>m+I.getHaveValid(),0);l=`${r.size(d)} (Ratio: ${r.ratioString(D.ratio(d,g))})`}if(b(i.info.uploaded,l),a.length===0)l=e;else if(a.every(d=>d.isStopped()))l=u;else{let d=m=>m.getStartDate(),g=d(a[0]);l=a.every(m=>d(m)===g)?r.timeInterval(s/1e3-g):t}if(b(i.info.running_time,l),a.length===0)l=e;else{let d=m=>m.getETA(),g=d(a[0]);a.every(m=>d(m)===g)?g<0?l=o:l=r.timeInterval(g):l=t}if(b(i.info.remaining_time,l),a.length===0)l=e;else{let d=a.reduce((m,I)=>Math.max(m,I.getLastActivity()),-1),g=Math.floor(s/1e3);if(0m.getErrorString(),g=d(a[0]);l=a.every(m=>d(m)===g)?g:t}if(b(i.info.error,l||e),a.length===1?l=a[0].getName():l=a.length>0?t:e,b(i.info.name,l),a.length===0)l=e;else{let d=a.reduce((g,m)=>g+m.getTotalSize(),0);if(d){let g=f=>f.getPieceSize(),m=a.reduce((f,C)=>f+C.getPieceCount(),0),I=r.number(m),G=g(a[0]);l=a.every(f=>g(f)===G)?`${r.size(d)} (${I} pieces @ ${r.mem(G)})`:`${r.size(d)} (${I} pieces)`}else l="None"}if(b(i.info.size,r.stringSanitizer(l)),a.length===0)l=e;else{let d=m=>m.getHashString(),g=d(a[0]);l=a.every(m=>d(m)===g)?g:t}if(b(i.info.hash,l),a.length===0)l=e;else{let d=m=>m.getPrivateFlag(),g=d(a[0]);a.every(m=>d(m)===g)?g?l="Private to this tracker -- DHT and PEX disabled":l="Public torrent":l=t}if(b(i.info.privacy,l),a.length===0)l=e;else{let d=m=>m.getComment(),g=d(a[0]);l=a.every(m=>d(m)===g)?g:t}if(l=l||e,l.startsWith("https://")||l.startsWith("http://")?(l=encodeURI(l),i.info.comment.innerHTML=`${l}`):b(i.info.comment,l),l=a.length===0?e:a[0].getLabels().join(", "),b(i.info.labels,l),a.length===0)l=e;else{let d=h=>h.getCreator(),g=d(a[0]),m=!a.every(h=>d(h)===g);d=h=>h.getDateCreated();let I=d(a[0]),G=!a.every(h=>d(h)===I),f=!g||g.length===0,C=!I;m||G?l=t:f&&C?l=o:C&&!f?l=`Created by ${g}`:f&&!C?l=`Created on ${new Date(I*1e3).toDateString()}`:l=`Created by ${g} on ${new Date(I*1e3).toDateString()}`}if(b(i.info.origin,l),a.length===0)l=e;else{let d=m=>m.getDownloadDir(),g=d(a[0]);l=a.every(m=>d(m)===g)?g:t}if(b(i.info.location,l),a.length===0)l=e;else{let d=m=>m.getDateAdded(),g=d(a[0]);l=a.every(m=>d(m)===g)?new Date(g*1e3).toLocaleString(navigator.language,{day:"2-digit",hour:"2-digit",hour12:!1,minute:"2-digit",month:"short",second:"2-digit",timeZoneName:"short",weekday:"short",year:"numeric"}):t}if(b(i.info.dateAdded,l),a.length===0)b(i.info.magnetLink,e);else if(a.length>1)b(i.info.magnetLink,t);else{let d=a[0].getMagnetLink();i.info.magnetLink.innerHTML=``}}static _peerStatusTitle(e){let t=Object.seal({"?":"We unchoked this peer, but they're not interested",D:"Downloading from this peer",E:"Encrypted Connection",H:"Peer was discovered through Distributed Hash Table (DHT)",I:"Peer is an incoming connection",K:"Peer has unchoked us, but we're not interested",O:"Optimistic unchoke",T:"Peer is connected via uTP",U:"Uploading to peer",X:"Peer was discovered through Peer Exchange (PEX)",d:"We would download from this peer if they'd let us",u:"We would upload to this peer if they'd ask"});return[...e].filter(o=>t[o]).map(o=>`${o}: ${t[o]}`).join(` -`)}_updatePeers(){let e=x,{elements:t,torrents:o}=this,{tbody:r}=t.peers,s=[(a,c)=>{c.dataset.encrypted=a.isEncrypted},(a,c)=>b(c,a.rateToPeer?e.speedBps(a.rateToPeer):""),(a,c)=>b(c,a.rateToClient?e.speedBps(a.rateToClient):""),(a,c)=>b(c,`${Math.floor(a.progress*100)}%`),(a,c)=>{b(c,a.flagStr),c.setAttribute("title",n._peerStatusTitle(a.flagStr))},(a,c)=>{b(c,a.address),c.setAttribute("title",a.address)},(a,c)=>{b(c,a.clientName),c.setAttribute("title",a.clientName)}],i=[];for(let a of o){let c=document.createElement("tr");c.classList.add("torrent-row");let l=document.createElement("td");l.setAttribute("colspan",s.length),b(l,a.getName()),c.append(l),i.push(c);for(let u of a.getPeers()){let d=document.createElement("tr");d.classList.add("peer-row");for(let[g,m]of s.entries()){let I=document.createElement("td");I.classList.add(Ge[g]),m(u,I),d.append(I)}i.push(d)}for(;r.firstChild;)r.firstChild.remove();r.append(...i)}}static getAnnounceState(e){switch(e.announceState){case A._TrackerActive:return"Announce in progress";case A._TrackerWaiting:{let t=Math.max(0,e.nextAnnounceTime-Date.now()/1e3);return`Next announce in ${x.timeInterval(t)}`}case A._TrackerQueued:return"Announce is queued";case A._TrackerInactive:return e.isBackup?"Tracker will be used as a backup":"Announce not scheduled";default:return`unknown announce state: ${e.announceState}`}}static lastAnnounceStatus(e){let t="Last Announce",o=["N/A"];if(e.hasAnnounced){let r=x.timestamp(e.lastAnnounceTime);e.lastAnnounceSucceeded?o=[r," (got ",x.countString("peer","peers",e.lastAnnouncePeerCount),")"]:(t="Announce error",o=[e.lastAnnounceResult?`${e.lastAnnounceResult} - `:"",r])}return{label:t,value:o.join("")}}static lastScrapeStatus(e){let t="Last Scrape",o="N/A";if(e.hasScraped){let r=x.timestamp(e.lastScrapeTime);e.lastScrapeSucceeded?o=r:(t="Scrape error",o=(e.lastScrapeResult?`${e.lastScrapeResult} - `:"")+r)}return{label:t,value:o}}static _getOrigin(e){try{let t="udp://";if(e.announce.startsWith(t)){let r="http://",s=e.announce.replace(t,r);return new URL(s).origin.replace(r,t)}return new URL(e.announce).origin}catch{return[e.sitename||e.host||e.announce]}}_updateTiers(){let{list:t}=this.elements.tiers,{torrents:o}=this,r=[];for(let s of o){if(o.length>1){let i=document.createElement("div");i.classList.add("tier-list-torrent"),b(i,s.getName()),r.push(i)}for(let i of s.getTrackers()){let a=n.getAnnounceState(i),c=n.lastAnnounceStatus(i),l=n.lastScrapeStatus(i),u=document.createElement("div");u.classList.add("tier-list-row");let d=document.createElement("div"),g=n._getOrigin(i);d.classList.add("tier-list-tracker"),b(d,`${g} - tier ${i.tier+1}`),d.setAttribute("title",i.announce),u.append(d),d=document.createElement("div"),d.classList.add("tier-announce"),b(d,`${c.label}: ${c.value}`),u.append(d),d=document.createElement("div"),d.classList.add("tier-seeders"),b(d,`Seeders: ${i.seederCount>-1?i.seederCount:"N/A"}`),u.append(d),d=document.createElement("div"),d.classList.add("tier-state"),b(d,a),u.append(d),d=document.createElement("div"),d.classList.add("tier-leechers"),b(d,`Leechers: ${i.leecherCount>-1?i.leecherCount:"N/A"}`),u.append(d),d=document.createElement("div"),d.classList.add("tier-scrape"),b(d,`${l.label}: ${l.value}`),u.append(d),d=document.createElement("div"),d.classList.add("tier-downloads"),b(d,`Downloads: ${i.downloadCount>-1?i.downloadCount:"N/A"}`),u.append(d),r.push(u)}}for(;t.firstChild;)t.firstChild.remove();t.append(...r)}_changeFileCommand(e,t){let{controller:o,file_torrent:r}=this,s=r.getId();o.changeFileCommand(s,e,t)}_onFileWantedToggled(e){let{indices:t,wanted:o}=e;this._changeFileCommand(t,o?"files-wanted":"files-unwanted")}_onFilePriorityToggled(e){let{indices:t,priority:o}=e,r=null;switch(o.toString()){case"-1":r="priority-low";break;case"1":r="priority-high";break;default:r="priority-normal"}this._changeFileCommand(t,r)}_clearFileList(){let{list:e}=this.elements.files;for(;e.firstChild;)e.firstChild.remove();this.file_torrent=null,this.file_torrent_n=null,this.file_rows=null}static createFileTreeModel(e){let t=[],o={children:{},file_indices:[]};for(let[r,s]of e.getFiles().entries()){let{name:i}=s,a=i.split("/"),c=o;for(let[l,u]of a.entries()){let d=c.children[u];d||(c.children[u]=d={children:{},depth:l,file_indices:[],name:u,parent:c}),c=d}c.file_index=r,delete c.children,t.push(c)}for(let r of t){let{file_index:s}=r,i=r;do i.file_indices.push(s),i=i.parent;while(i)}return o}addNodeToView(e,t,o){let r=new oe(this.controller,e,o);r.addEventListener("wantedToggled",this._onFileWantedToggled.bind(this)),r.addEventListener("priorityToggled",this._onFilePriorityToggled.bind(this)),this.file_rows.push(r),t.append(r.getElement())}addSubtreeToView(e,t,o){if(o.parent&&this.addNodeToView(e,t,o),o.children)for(let r of Object.values(o.children))this.addSubtreeToView(e,t,r)}_updateFiles(){let{list:e}=this.elements.files,{file_rows:t,file_torrent:o,file_torrent_n:r,torrents:s}=this;if(s.length!==1){this._clearFileList();return}let[i]=s,a=i.getFiles().length;if(i!==o||a!==r){this._clearFileList(),this.file_torrent=i,this.file_torrent_n=a,this.file_rows=[];let c=document.createDocumentFragment(),l=n.createFileTreeModel(i);this.addSubtreeToView(i,c,l),e.append(c)}else for(let c of t)c.refresh()}};var re=class n extends EventTarget{constructor(e,t){super(),this.controller=e,this.remote=t,this.elements={},this.torrents=[],this.show()}show(){let e=this.controller.getSelectedTorrents();e.length!==0&&(this.torrents=e,this.elements=n._create(),this.elements.confirm.addEventListener("click",()=>this._onConfirm()),this.elements.dismiss.addEventListener("click",()=>this._onDismiss()),this.elements.entry.value=e[0].getDownloadDir(),document.body.append(this.elements.root),this.elements.entry.focus())}close(){this.elements.root.remove(),this.dispatchEvent(new Event("close")),delete this.controller,delete this.remote,delete this.elements,delete this.torrents}_onDismiss(){this.close()}_onConfirm(){let e=this.torrents.map(o=>o.getId()),t=this.elements.entry.value.trim();this.remote.moveTorrents(e,t),this.close()}static _create(){let e=X("move-dialog");e.root.setAttribute("aria-label","Move Torrent"),e.heading.textContent="Set Torrent Location",confirm.textContent="Apply";let t=document.createElement("label");t.setAttribute("for","torrent-path"),t.textContent="Location:",e.workarea.append(t);let o=document.createElement("input");return o.setAttribute("type","text"),o.id="torrent-path",e.entry=o,e.workarea.append(o),e}};var k=class n extends EventTarget{constructor(e){super(),this.elements=n._create(e),this.elements.dismiss.addEventListener("click",()=>this._onDismiss()),this.options=e,document.body.append(this.elements.root),this.elements.dismiss.focus()}close(){if(!this.closed){this.elements.root.remove(),this.dispatchEvent(new Event("close"));for(let e of Object.keys(this))delete this[e];this.closed=!0}}_onDismiss(){this.close()}static _create(e){let{heading:t,message:o}=e,r=X("confirm-dialog");return r.confirm.remove(),delete r.confirm,r.heading.textContent=t,r.workarea.textContent=o,r}};var B={_DaemonVersion:"version",_DownSpeedLimit:"speed-limit-down",_DownSpeedLimited:"speed-limit-down-enabled",_JsonRpcVersion:"2.0",_QueueMoveBottom:"queue-move-bottom",_QueueMoveDown:"queue-move-down",_QueueMoveTop:"queue-move-top",_QueueMoveUp:"queue-move-up",_Root:"../rpc",_TurtleDownSpeedLimit:"alt-speed-down",_TurtleState:"alt-speed-enabled",_TurtleUpSpeedLimit:"alt-speed-up",_UpSpeedLimit:"speed-limit-up",_UpSpeedLimited:"speed-limit-up-enabled"},J=class n{_connection_alert=null;_session_id="";constructor(e){this._controller=e}sendRequest(e,t,o){let r=new Headers;r.append("cache-control","no-cache"),r.append("content-type","application/json"),r.append("pragma","no-cache"),this._session_id&&r.append(n._SessionHeader,this._session_id);let s=null;fetch(B._Root,{body:JSON.stringify(e),headers:r,method:"POST"}).then(i=>{switch(s=i,i.status){case 409:{let a=new Error(n._SessionHeader);throw a.header=i.headers.get(n._SessionHeader),a}case 204:return null;default:return i.json()}}).then(i=>{t&&t.call(o,i,s),this._connection_alert&&(this._connection_alert.close(),this._connection_alert=null)}).catch(i=>{if(i.message===n._SessionHeader){this._session_id=i.header,this.sendRequest(e,t,o);return}console.trace(i),this._controller.togglePeriodicSessionRefresh(!1),this._connection_alert=new k({heading:"Connection failed",message:"Could not connect to the server. You may need to reload the page to reconnect."}),this._controller.setCurrentPopup(this._connection_alert)})}loadDaemonPrefs(e,t){let o={id:"webui",jsonrpc:B._JsonRpcVersion,method:"session-get"};this.sendRequest(o,e,t)}checkPort(e,t,o){let r={id:"webui",jsonrpc:B._JsonRpcVersion,method:"port-test",params:{ip_protocol:e}};this.sendRequest(r,t,o)}renameTorrent(e,t,o,r,s){let i={id:"webui",jsonrpc:B._JsonRpcVersion,method:"torrent-rename-path",params:{ids:e,name:o,path:t}};this.sendRequest(i,r,s)}setLabels(e,t,o){let r={ids:e,labels:t};this.sendRequest({id:"webui",jsonrpc:B._JsonRpcVersion,method:"torrent-set",params:r},o)}loadDaemonStats(e,t){let o={id:"webui",jsonrpc:B._JsonRpcVersion,method:"session-stats"};this.sendRequest(o,e,t)}updateTorrents(e,t,o,r){let s={id:"webui",jsonrpc:B._JsonRpcVersion,method:"torrent-get",params:{fields:t,format:"table"}};e&&(s.params.ids=e),this.sendRequest(s,i=>{let{torrents:a,removed:c}=i.result;o.call(r,a,c)})}getFreeSpace(e,t,o){let r={id:"webui",jsonrpc:B._JsonRpcVersion,method:"free-space",params:{path:e}};this.sendRequest(r,s=>{let{path:i,"size-bytes":a}=s.result;t.call(o,i,a)})}changeFileCommand(e,t,o){let r={ids:[e]};r[o]=t,this.sendRequest({jsonrpc:B._JsonRpcVersion,method:"torrent-set",params:r},()=>{this._controller.refreshTorrents([e])})}sendTorrentSetRequests(e,t,o,r,s){o||={},o.ids=t;let i={id:"webui",jsonrpc:B._JsonRpcVersion,method:e,params:o};this.sendRequest(i,r,s)}sendTorrentActionRequests(e,t,o,r){this.sendTorrentSetRequests(e,t,null,o,r)}startTorrents(e,t,o,r){let s=t?"torrent-start-now":"torrent-start";this.sendTorrentActionRequests(s,e,o,r)}stopTorrents(e,t,o){this.sendTorrentActionRequests("torrent-stop",e,t,o)}moveTorrents(e,t,o,r){this.sendTorrentSetRequests("torrent-set-location",e,{location:t,move:!0},o,r)}removeTorrents(e,t){let o={jsonrpc:B._JsonRpcVersion,method:"torrent-remove",params:{"delete-local-data":t,ids:[]}};if(e)for(let r=0,s=e.length;r{this._controller.refreshTorrents()})}verifyTorrents(e,t,o){this.sendTorrentActionRequests("torrent-verify",e,t,o)}reannounceTorrents(e,t,o){this.sendTorrentActionRequests("torrent-reannounce",e,t,o)}addTorrentByUrl(e,t){/^[\da-f]{40}$/i.test(e)&&(e=`magnet:?xt=urn:btih:${e}`);let o={jsonrpc:B._JsonRpcVersion,method:"torrent-add",params:{filename:e,paused:t.paused}};this.sendRequest(o,()=>{this._controller.refreshTorrents()})}savePrefs(e){let t={jsonrpc:B._JsonRpcVersion,method:"session-set",params:e};this.sendRequest(t,()=>{this._controller.loadDaemonPrefs()})}updateBlocklist(){let e={jsonrpc:B._JsonRpcVersion,method:"blocklist-update"};this.sendRequest(e,()=>{this._controller.loadDaemonPrefs()})}moveTorrentsToTop(e,t,o){this.sendTorrentActionRequests(B._QueueMoveTop,e,t,o)}moveTorrentsToBottom(e,t,o){this.sendTorrentActionRequests(B._QueueMoveBottom,e,t,o)}moveTorrentsUp(e,t,o){this.sendTorrentActionRequests(B._QueueMoveUp,e,t,o)}moveTorrentsDown(e,t,o){this.sendTorrentActionRequests(B._QueueMoveDown,e,t,o)}};J._SessionHeader="X-Transmission-Session-Id";var De=/iPad|iPhone|iPod/.test(navigator.userAgent)&&!globalThis.MSStream,Ee=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),Je=!(De&&Ee),V=class extends EventTarget{constructor(e,t,o="",r=null){super(),this.controller=e,this.remote=t,this.elements=this._create(o),this.elements.dismiss.addEventListener("click",()=>this._onDismiss()),this.elements.confirm.addEventListener("click",()=>this._onConfirm()),document.body.append(this.elements.root),r&&(this.elements.file_input.files=r),this._updateFreeSpaceInAddDialog(),this.elements.url_input.focus()}close(){if(!this.closed){clearInterval(this.interval),this.elements.root.remove(),this.dispatchEvent(new Event("close"));for(let e of Object.keys(this))delete this[e];this.closed=!0}}_onDismiss(){this.close()}_updateFreeSpaceInAddDialog(){let e=this.elements.folder_input.value;this.remote.getFreeSpace(e,(t,o)=>{this.closed||(this.elements.freespace.textContent=o>0?`${x.size(o)} Free`:"")})}_onConfirm(){let{controller:e,elements:t,remote:o}=this,{file_input:r,folder_input:s,start_input:i,url_input:a}=t,c=!i.checked,l=s.value.trim();for(let d of r.files){let g=new FileReader;g.addEventListener("load",m=>{let I=m.target.result,G="base64,",f=I.indexOf(G);if(f===-1)return;let C={id:"webui",jsonrpc:B._JsonRpcVersion,method:"torrent-add",params:{"download-dir":l,metainfo:I.slice(Math.max(0,f+G.length)),paused:c}};o.sendRequest(C,h=>{if("error"in h){let y=h.error.data?.errorString??h.error.message;alert(`Error adding "${d.name}": ${y}`),e.setCurrentPopup(new k({heading:`Error adding "${d.name}"`,message:y}))}})}),g.readAsDataURL(d)}let u=a.value.trim();if(u.length>0){/^[\da-f]{40}$/i.test(u)&&(u=`magnet:?xt=urn:btih:${u}`);let d={id:"webui",jsonrpc:B._JsonRpcVersion,method:"torrent-add",params:{"download-dir":l,filename:u,paused:c}};o.sendRequest(d,g=>{"error"in g&&e.setCurrentPopup(new k({heading:`Error adding "${u}"`,message:g.error.data?.errorString??g.error.message}))})}this._onDismiss()}_create(e){let t=X(),{confirm:o,root:r,heading:s,workarea:i}=t;r.classList.add("open-torrent"),s.textContent="Add Torrents",o.textContent="Add";let a=v(),c=document.createElement("label");c.setAttribute("for",a),c.textContent="Please select torrent files to add:",i.append(c);let l=document.createElement("input");l.type="file",l.name="torrent-files[]",l.id=a,l.multiple=!0,Je&&(l.accept=".torrent,application/x-bittorrent"),i.append(l),t.file_input=l,a=v(),c=document.createElement("label"),c.setAttribute("for",a),c.textContent="Or enter a URL:",i.append(c),l=document.createElement("input"),l.type="url",l.id=a,l.value=e,i.append(l),t.url_input=l,a=v(),c=document.createElement("label"),c.id="add-dialog-folder-label",c.for=a,c.textContent="Destination folder: ",i.append(c);let u=document.createElement("span");u.id="free-space-text",c.append(u),i.append(c),t.freespace=u,l=document.createElement("input"),l.type="text",l.id="add-dialog-folder-input",l.addEventListener("change",()=>this._updateFreeSpaceInAddDialog()),l.value=this.controller.session_properties["download-dir"],i.append(l),t.folder_input=l;let d=document.createElement("div");i.append(d);let g=document.createElement("input");return g.type="checkbox",g.id="auto-start-check",g.checked=this.controller.shouldAddedTorrentsStart(),d.append(g),t.start_input=g,c=document.createElement("label"),c.id="auto-start-label",c.setAttribute("for",g.id),c.textContent="Start when added",d.append(c),t}};function se(n,e){let t=document.createElement("fieldset");t.classList.add("section",n);let o=document.createElement("legend");return o.classList.add("title"),o.textContent=e,t.append(o),t}function xe(n,e,t,o){let r=document.createElement("button");return r.textContent=e,r.addEventListener("click",o),n.append(r),r.dataset.action=t,r}var _=class extends EventTarget{constructor(e,t,o,r){super(),this.action_listener=this._onActionChange.bind(this),this.action_manager=r,this.action_manager.addEventListener("change",this.action_listener),this.prefs_listener=this._onPrefsChange.bind(this),this.prefs=t,this.prefs.addEventListener("change",this.prefs_listener),this.closed=!1,this.remote=o,this.name="overflow-menu",this.session_listener=this._onSessionChange.bind(this),this.session_manager=e,this.session_manager.addEventListener("session-change",this.session_listener);let{session_properties:s}=e;Object.assign(this,this._create(s)),this.outside=new T(this.root),this.outside.addEventListener("click",()=>this.close()),Object.seal(this),this.show()}show(){document.body.append(this.root)}close(){if(!this.closed){this.outside.stop(),this.session_manager.removeEventListener("session-change",this.session_listener),this.action_manager.removeEventListener("change",this.action_listener),this.prefs.removeEventListener("change",this.prefs_listener),this.root.remove(),this.dispatchEvent(new Event("close"));for(let e of Object.keys(this))this[e]=null;this.closed=!0}}_onSessionChange(e){let{alt_speed_check:t}=this.elements,{session_properties:o}=e;t.checked=o[B._TurtleState]}_onPrefsChange(e){switch(e.key){case p.SortDirection:case p.SortMode:this.root.querySelector(`[data-pref="${e.key}"]`).value=e.value;break;default:break}}_onActionChange(e){let t=this.actions[e.action];t&&this._updateElement(t)}_updateElement(e){if(e.dataset.action){let{action:t}=e.dataset,o=this.action_manager.keyshortcuts(t);o&&e.setAttribute("aria-keyshortcuts",o),L(e,this.action_manager.isEnabled(t))}}_onClick(e){let{action:t,pref:o}=e.target.dataset;if(t){this.action_manager.click(t);return}if(o){this.prefs[o]=e.target.value;return}console.log("unhandled"),console.log(e),console.trace()}_create(e){let t={},o={},r=this._onClick.bind(this),s=document.createElement("div");s.classList.add("overflow-menu","popup");let i=document.createElement("div"),a=(C,h)=>{let y=document.createElement("input");y.id=v(),y.type="checkbox";let U=document.createElement("label");U.htmlFor=y.id,U.textContent=C,i.append(y,U),h(y)},c=se("display","Display");s.append(c);let l=document.createElement("div");l.id="display-options",c.append(l),i.classList.add("table-row"),l.append(i);let u=document.createElement("label");u.id="display-sort-mode-label",u.textContent="Sort by",i.append(u);let d=document.createElement("select");d.id="display-sort-mode-select",d.dataset.pref=p.SortMode,i.append(d);let g=[[p.SortByActivity,"Activity"],[p.SortByAge,"Age"],[p.SortByName,"Name"],[p.SortByProgress,"Progress"],[p.SortByQueue,"Queue order"],[p.SortByRatio,"Ratio"],[p.SortBySize,"Size"],[p.SortByState,"State"]];for(let[C,h]of g){let y=document.createElement("option");y.value=C,y.textContent=h,d.append(y)}u.htmlFor=d.id,d.value=this.prefs.sort_mode,d.addEventListener("change",C=>{this.prefs.sort_mode=C.target.value}),i=document.createElement("div"),i.classList.add("table-row"),l.append(i);let m=C=>{C.dataset.pref=p.SortDirection,C.checked=this.prefs.sort_direction!==p.SortAscending,C.addEventListener("input",h=>{this.prefs.sort_direction=h.target.checked?p.SortDescending:p.SortAscending})};a("Reverse sort",m),i=document.createElement("div"),i.classList.add("table-row"),l.append(i),m=C=>{C.checked=this.prefs.display_mode===p.DisplayCompact,C.addEventListener("change",h=>{let{checked:y}=h.target;this.prefs.display_mode=y?p.DisplayCompact:p.DisplayFull})},a(this.action_manager.text("toggle-compact-rows"),m),i=document.createElement("div"),i.classList.add("table-row"),l.append(i),m=C=>{C.checked=this.prefs.contrast_mode===p.ContrastMore,C.addEventListener("change",h=>{let{checked:y}=h.target;this.prefs.contrast_mode=y?p.ContrastMore:p.ContrastLess})},a(this.action_manager.text("toggle-contrast"),m),i=document.createElement("div"),i.classList.add("table-row","display-fullscreen-row"),l.append(i),m=C=>{let h=()=>document.fullscreenElement!==null;C.checked=h(),document.addEventListener("fullscreenchange",()=>{C.checked=h()}),C.addEventListener("change",()=>{h()?document.exitFullscreen():document.body.requestFullscreen()})},a("Fullscreen",m),c=se("speed","Speed Limit"),s.append(c),l=document.createElement("div"),l.id="speed-options",c.append(l),i=document.createElement("div"),i.classList.add("speed-up"),l.append(i),u=document.createElement("label"),u.id="speed-up-label",u.textContent="Upload:",i.append(u);let I="Unlimited";d=document.createElement("select"),d.id="speed-up-select",i.append(d);let G=["50","100","250","500","1000","2500","5000","10000",I];for(let C of[...new Set(G).add(`${e[B._UpSpeedLimit]}`).values()].toSorted((h,y)=>h-y)){let h=document.createElement("option");h.value=C,h.textContent=C===I?I:x.speed(C),d.append(h)}u.htmlFor=d.id,d.value=e[B._UpSpeedLimited]?`${e[B._UpSpeedLimit]}`:I,d.addEventListener("change",C=>{let{value:h}=C.target;console.log(C),h===I?this.remote.savePrefs({[B._UpSpeedLimited]:!1}):this.remote.savePrefs({[B._UpSpeedLimited]:!0,[B._UpSpeedLimit]:Number.parseInt(h,10)})}),i=document.createElement("div"),i.classList.add("speed-down"),l.append(i),u=document.createElement("label"),u.id="speed-down-label",u.textContent="Download:",i.append(u),d=document.createElement("select"),d.id="speed-down-select",i.append(d);for(let C of[...new Set(G).add(`${e[B._DownSpeedLimit]}`).values()].toSorted((h,y)=>h-y)){let h=document.createElement("option");h.value=C,h.textContent=C===I?I:x.speed(C),d.append(h)}u.htmlFor=d.id,d.value=e[B._DownSpeedLimited]?`${e[B._DownSpeedLimit]}`:I,d.addEventListener("change",C=>{let{value:h}=C.target;console.log(C),h===I?this.remote.savePrefs({[B._DownSpeedLimited]:!1}):this.remote.savePrefs({[B._DownSpeedLimited]:!0,[B._DownSpeedLimit]:Number.parseInt(h,10)})}),i=document.createElement("div"),i.classList.add("alt-speed"),l.append(i),m=C=>{C.checked=e[B._TurtleState],o.alt_speed_check=C,C.addEventListener("change",O=>{this.remote.savePrefs({[B._TurtleState]:O.target.checked})});let h=document.createElement("label");h.htmlFor=C.id,h.id="alt-speed-image";let y=document.createElement("label");y.htmlFor=C.id;let U=x.speed(e[B._TurtleUpSpeedLimit]),H=x.speed(e[B._TurtleDownSpeedLimit]);y.textContent=`(${U} up, ${H} down)`,i.append(h,y)},a("Use Temp limits",m),c=se("actions","Actions"),s.append(c);for(let C of["show-preferences-dialog","show-shortcuts-dialog","pause-all-torrents","start-all-torrents"]){let h=this.action_manager.text(C);t[C]=xe(c,h,C,r)}c=se("help","Help"),s.append(c),l=document.createElement("div"),c.append(l);for(let C of["show-statistics-dialog","show-about-dialog"]){let h=this.action_manager.text(C);t[C]=xe(l,h,C,r)}let f=document.createElement("a");return f.href="https://transmissionbt.com/donate.html",f.target="_blank",f.textContent="Donate",l.append(f),this._updateElement=this._updateElement.bind(this),{actions:t,elements:o,root:s}}};var ie=class n extends EventTarget{static _initTimeDropDown(e){for(let t=0;t<96;++t){let o=t/4,r=t%4*15,s=t*15,i=`${o}:${r||"00"}`;e.options[t]=new Option(i,s)}}static _initDayDropDown(e){let t=[["Everyday","127"],["Weekdays","62"],["Weekends","65"],["Sunday","1"],["Monday","2"],["Tuesday","4"],["Wednesday","8"],["Thursday","16"],["Friday","32"],["Saturday","64"]];for(let o=0;t[o];++o){let[r,s]=t[o];e.options[o]=new Option(r,s)}}_checkPort(){for(let[e,t]of Object.entries(this.elements.network.port_status_label))delete t.dataset.open,b(t,"Checking..."),this.remote.checkPort(e,o=>this._onPortChecked(e,o),this)}_onPortChecked(e,t){if(this.closed)return;let o=t.result??t.error?.data??{},r=this.elements.network.port_status_label[e],s=o["port-is-open"]??!1;r.dataset.open=s,"port-is-open"in o?b(r,s?"Open":"Closed"):b(r,"Error")}_setBlocklistButtonEnabled(e){let t=this.elements.peers.blocklist_update_button;L(t,e),t.value=e?"Update":"Updating..."}static _getValue(e){if(e.tagName==="TEXTAREA")return e.value;switch(e.type){case"checkbox":case"radio":return e.checked;case"number":case"select-one":case"text":case"url":{let t=e.value;return Number.parseInt(t,10).toString()===t?Number.parseInt(t,10):Number.parseFloat(t).toString()===t?Number.parseFloat(t):t}default:return null}}_onMaybePortChanged(e){(e==="peer-port"||e==="port-forwarding-enabled")&&this._checkPort()}_onControlChanged(e){let{key:t}=e.target.dataset;this.remote.savePrefs({[t]:n._getValue(e.target)}),this._onMaybePortChanged(t)}_onDialogClosed(){this.dispatchEvent(new Event("closed"))}_update(){this._setBlocklistButtonEnabled(!0);for(let[e,t]of Object.entries(this.session_manager.session_properties))for(let o of this.elements.root.querySelectorAll(`[data-key="${e}"]`)){if(e==="blocklist-size"){let r=x.number(t);o.innerHTML=`Blocklist has ${r} rules`,b(this.elements.peers.blocklist_update_button,"Update")}else switch(o.type){case"checkbox":case"radio":o.checked=t;break;case"text":case"textarea":case"url":case"email":case"number":case"search":o!==document.activeElement&&(o.value!=t&&this._onMaybePortChanged(e),o.value=t);break;case"select-one":o.value=t;break;default:console.log(o.type);break}o.dispatchEvent(new Event("session-change"))}}shouldAddedTorrentsStart(){return this.data.elements.root.find("#start-added-torrents")[0].checked}static _createCheckAndLabel(e,t){let o=document.createElement("div");o.id=e;let r=document.createElement("input");r.id=v(),r.type="checkbox",o.append(r);let s=document.createElement("label");return s.textContent=t,s.setAttribute("for",r.id),o.append(s),{check:r,label:s,root:o}}static _enableIfChecked(e,t){let o=()=>{e.tagName==="INPUT"?L(e,t.checked):e.classList.toggle("disabled",!t.checked)};t.addEventListener("session-change",o),o()}static _getProtocolHandlerRegistered(){return localStorage.getItem("protocol-handler-registered")==="true"}static _updateProtocolHandlerButton(e){e.removeAttribute("disabled"),e.removeAttribute("title"),n._getProtocolHandlerRegistered()?(e.textContent="Remove Browser Handler","unregisterProtocolHandler"in navigator||e.setAttribute("title","Your browser does not support removing protocol handlers. This button only allows you to re-register a handler.")):(e.textContent="Add Browser Handler",e.removeAttribute("title"),"registerProtocolHandler"in navigator||(e.setAttribute("disabled",!0),e.setAttribute("title","Your browser does not support protocol handlers")))}static _toggleProtocolHandler(e){let t=new URL(globalThis.location.href);t.search="addtorrent=%s",this._getProtocolHandlerRegistered()?(navigator.unregisterProtocolHandler?.("magnet",t.toString()),localStorage.removeItem("protocol-handler-registered"),n._updateProtocolHandlerButton(e)):(navigator.registerProtocolHandler("magnet",t.toString(),"Transmission Web"),localStorage.setItem("protocol-handler-registered","true"),n._updateProtocolHandlerButton(e))}static _createTorrentsPage(){let e=document.createElement("div");e.classList.add("prefs-torrents-page");let t=document.createElement("div");t.textContent="Downloading",t.classList.add("section-label"),e.append(t),t=document.createElement("label"),t.textContent="Download to:",e.append(t);let o=document.createElement("input");o.type="text",o.id=v(),o.dataset.key="download-dir",t.setAttribute("for",o.id),e.append(o);let r=o,s=n._createCheckAndLabel("incomplete-dir-div","Use temporary folder:");s.check.title="Separate folder to temporarily store downloads until they are complete.",s.check.dataset.key="incomplete-dir-enabled",s.label.title=s.check.title,e.append(s.root);let i=s.check;o=document.createElement("input"),o.type="text",o.dataset.key="incomplete-dir",e.append(o),n._enableIfChecked(o,s.check);let a=o;s=n._createCheckAndLabel("autostart-div","Start when added"),s.check.dataset.key="start-added-torrents",e.append(s.root);let c=s.check;s=n._createCheckAndLabel("suffix-div",`Append "part" to incomplete files' names`),s.check.dataset.key="rename-partial-files",e.append(s.root);let l=s.check;s=n._createCheckAndLabel("download-queue-div","Download queue size:"),s.check.dataset.key="download-queue-enabled",e.append(s.root);let u=s.check;o=document.createElement("input"),o.type="number",o.dataset.key="download-queue-size",e.append(o),n._enableIfChecked(o,s.check);let d=o;t=document.createElement("div"),t.textContent="Seeding",t.classList.add("section-label"),e.append(t),s=n._createCheckAndLabel("stop-ratio-div","Stop seeding at ratio:"),s.check.dataset.key="seedRatioLimited",e.append(s.root);let g=s.check;o=document.createElement("input"),o.type="number",o.min="0.1",o.step="any",o.dataset.key="seedRatioLimit",e.append(o),n._enableIfChecked(o,s.check);let m=o;s=n._createCheckAndLabel("stop-idle-div","Stop seeding if idle for N mins:"),s.check.dataset.key="idle-seeding-limit-enabled",e.append(s.root);let I=s.check;o=document.createElement("input"),o.type="number",o.min="0.1",o.step="any",o.dataset.key="idle-seeding-limit",e.append(o),n._enableIfChecked(o,s.check);let G=o;t=document.createElement("div"),t.textContent="Magnet Protocol Handler",t.classList.add("section-label"),e.append(t);let f=document.createElement("button");return f.classList.add("register-handler-button"),n._updateProtocolHandlerButton(f),e.append(f),{autostart_check:c,download_dir:r,download_queue_check:u,download_queue_input:d,incomplete_dir_check:i,incomplete_dir_input:a,register_handler_button:f,root:e,stop_idle_check:I,stop_idle_input:G,stop_ratio_check:g,stop_ratio_input:m,suffix_check:l}}static _createSpeedPage(){let e=document.createElement("div");e.classList.add("prefs-speed-page");let t=document.createElement("div");t.textContent="Speed Limits",t.classList.add("section-label"),e.append(t);let o=n._createCheckAndLabel("upload-speed-div","Upload (kB/s):");o.check.dataset.key="speed-limit-up-enabled",e.append(o.root);let r=o.check,s=document.createElement("input");s.type="number",s.dataset.key="speed-limit-up",e.append(s),n._enableIfChecked(s,o.check);let i=s;o=n._createCheckAndLabel("download-speed-div","Download (kB/s):"),o.check.dataset.key="speed-limit-down-enabled",e.append(o.root);let a=o.check;s=document.createElement("input"),s.type="number",s.dataset.key="speed-limit-down",e.append(s),n._enableIfChecked(s,o.check);let c=s;t=document.createElement("div"),t.textContent="Alternative Speed Limits",t.classList.add("section-label","alt-speed-section-label"),e.append(t),t=document.createElement("div"),t.textContent="Override normal speed limits manually or at scheduled times",t.classList.add("alt-speed-label"),e.append(t),t=document.createElement("label"),t.textContent="Upload (kB/s):",e.append(t),s=document.createElement("input"),s.type="number",s.dataset.key="alt-speed-up",s.id=v(),t.setAttribute("for",s.id),e.append(s);let l=s;t=document.createElement("label"),t.textContent="Download (kB/s):",e.append(t),s=document.createElement("input"),s.type="number",s.dataset.key="alt-speed-down",s.id=v(),t.setAttribute("for",s.id),e.append(s);let u=s;o=n._createCheckAndLabel("alt-times-div","Scheduled times"),o.check.dataset.key="alt-speed-time-enabled",e.append(o.root);let d=o.check;t=document.createElement("label"),t.textContent="From:",n._enableIfChecked(t,o.check),e.append(t);let g=document.createElement("select");g.id=v(),g.dataset.key="alt-speed-time-begin",n._initTimeDropDown(g),t.setAttribute("for",g.id),e.append(g),n._enableIfChecked(g,o.check);let m=g;t=document.createElement("label"),t.textContent="To:",n._enableIfChecked(t,o.check),e.append(t),g=document.createElement("select"),g.id=v(),g.dataset.key="alt-speed-time-end",n._initTimeDropDown(g),t.setAttribute("for",g.id),e.append(g),n._enableIfChecked(g,o.check);let I=g;return t=document.createElement("label"),t.textContent="On days:",n._enableIfChecked(t,o.check),e.append(t),g=document.createElement("select"),g.id=v(),g.dataset.key="alt-speed-time-day",n._initDayDropDown(g),t.setAttribute("for",g.id),e.append(g),n._enableIfChecked(g,o.check),{alt_days_select:g,alt_download_speed_input:u,alt_from_select:m,alt_times_check:d,alt_to_select:I,alt_upload_speed_input:l,download_speed_check:a,download_speed_input:c,root:e,upload_speed_check:r,upload_speed_input:i}}static _createPeersPage(){let e=document.createElement("div");e.classList.add("prefs-peers-page");let t=document.createElement("div");t.textContent="Connections",t.classList.add("section-label"),e.append(t),t=document.createElement("label"),t.textContent="Max peers per torrent:",e.append(t);let o=document.createElement("input");o.type="number",o.dataset.key="peer-limit-per-torrent",o.id=v(),t.setAttribute("for",o.id),e.append(o);let r=o;t=document.createElement("label"),t.textContent="Max peers overall:",e.append(t),o=document.createElement("input"),o.type="number",o.dataset.key="peer-limit-global",o.id=v(),t.setAttribute("for",o.id),e.append(o);let s=o;t=document.createElement("div"),t.textContent="Options",t.classList.add("section-label"),e.append(t),t=document.createElement("label"),t.textContent="Encryption mode:",e.append(t);let i=document.createElement("select");i.id=v(),i.dataset.key="encryption",i.options[0]=new Option("Prefer encryption","preferred"),i.options[1]=new Option("Allow encryption","tolerated"),i.options[2]=new Option("Require encryption","required"),e.append(i);let a=i,c=n._createCheckAndLabel("use-pex-div","Use PEX to find more peers");c.check.title="PEX is a tool for exchanging peer lists with the peers you're connected to.",c.check.dataset.key="pex-enabled",c.label.title=c.check.title,e.append(c.root);let l=c.check;c=n._createCheckAndLabel("use-dht-div","Use DHT to find more peers"),c.check.title="DHT is a tool for finding peers without a tracker.",c.check.dataset.key="dht-enabled",c.label.title=c.check.title,e.append(c.root);let u=c.check;c=n._createCheckAndLabel("use-lpd-div","Use LPD to find more peers"),c.check.title="LPD is a tool for finding peers on your local network.",c.check.dataset.key="lpd-enabled",c.label.title=c.check.title,e.append(c.root);let d=c.check;t=document.createElement("div"),t.textContent="Blocklist",t.classList.add("section-label"),e.append(t),c=n._createCheckAndLabel("blocklist-enabled-div","Enable blocklist:"),c.check.dataset.key="blocklist-enabled",e.append(c.root);let g=c.check;o=document.createElement("input"),o.type="url",o.value="http://www.example.com/blocklist",o.dataset.key="blocklist-url",e.append(o),n._enableIfChecked(o,c.check);let m=o;t=document.createElement("label"),t.textContent="Blocklist has {n} rules",t.dataset.key="blocklist-size",t.classList.add("blocklist-size-label"),n._enableIfChecked(t,c.check),e.append(t);let I=document.createElement("button");return I.classList.add("blocklist-update-button"),I.textContent="Update",e.append(I),n._enableIfChecked(I,c.check),{blocklist_enabled_check:g,blocklist_update_button:I,blocklist_url_input:m,dht_check:u,encryption_select:a,lpd_check:d,max_peers_overall_input:s,max_peers_per_torrent_input:r,pex_check:l,root:e}}static _createNetworkPage(){let e=document.createElement("div");e.classList.add("prefs-network-page");let t=document.createElement("div");t.textContent="Listening Port",t.classList.add("section-label"),e.append(t),t=document.createElement("label"),t.textContent="Peer listening port:",e.append(t);let o=document.createElement("input");o.type="number",o.dataset.key="peer-port",o.id=v(),t.setAttribute("for",o.id),e.append(o);let r=o,s=document.createElement("div");s.classList.add("port-status"),t=document.createElement("label"),t.textContent="IPv4 port is",s.append(t);let i=document.createElement("label");i.textContent="?",i.classList.add("port-status-label"),s.append(i),s.append(document.createElement("br")),t=document.createElement("label"),t.textContent="IPv6 port is",s.append(t);let a=document.createElement("label");a.textContent="?",a.classList.add("port-status-label"),s.append(a),e.append(s);let c=n._createCheckAndLabel("randomize-port","Randomize port on launch");c.check.dataset.key="peer-port-random-on-start",e.append(c.root);let l=c.check;c=n._createCheckAndLabel("port-forwarding","Use port forwarding from my router"),c.check.dataset.key="port-forwarding-enabled",e.append(c.root);let u=c.check;t=document.createElement("div"),t.textContent="Options",t.classList.add("section-label"),e.append(t),c=n._createCheckAndLabel("utp-enabled","Enable uTP for peer communication"),c.check.dataset.key="utp-enabled",e.append(c.root);let d=c.check;t=document.createElement("div"),t.textContent="Default Public Trackers",t.classList.add("section-label"),e.append(t);let g=["Trackers to use on all public torrents.","To add a backup URL, add it on the next line after a primary URL.","To add a new primary URL, add it after a blank line."];for(let G of g)t=document.createElement("label"),t.classList.add("default-trackers-label"),t.textContent=G,t.setAttribute("for","default-trackers"),e.append(t);let m=document.createElement("textarea");return m.dataset.key="default-trackers",m.id="default-trackers",e.append(m),{default_trackers_textarea:m,port_forwarding_check:u,port_input:r,port_status_label:{ipv4:i,ipv6:a},random_port_check:l,root:e,utp_check:d}}static _create(){let e={network:n._createNetworkPage(),peers:n._createPeersPage(),speed:n._createSpeedPage(),torrents:n._createTorrentsPage()};return{...M("prefs-dialog",[["prefs-tab-torrent",e.torrents.root,"Torrents"],["prefs-tab-speed",e.speed.root,"Speed"],["prefs-tab-peers",e.peers.root,"Peers"],["prefs-tab-network",e.network.root,"Network"]]),...e}}constructor(e,t){super(),this.closed=!1,this.session_manager=e,this.remote=t,this.update_from_session=()=>this._update(),this.elements=n._create(),this.elements.peers.blocklist_update_button.addEventListener("click",s=>{b(s.target,"Updating blocklist..."),this.remote.updateBlocklist(),this._setBlocklistButtonEnabled(!1)}),this.elements.torrents.register_handler_button.addEventListener("click",s=>{n._toggleProtocolHandler(s.currentTarget)}),this.elements.dismiss.addEventListener("click",()=>this.close()),this.outside=new T(this.elements.root),this.outside.addEventListener("click",()=>this.close()),Object.seal(this);let o=this._onControlChanged.bind(this),r=s=>{for(let i of Object.values(s))if(i.tagName==="INPUT")switch(i.type){case"checkbox":case"radio":case"number":case"text":case"url":i.addEventListener("change",o);break;default:console.trace(`unhandled input: ${i.type}`);break}else(i.tagName==="TEXTAREA"||i.tagName==="SELECT")&&i.addEventListener("change",o)};r(this.elements.network),r(this.elements.peers),r(this.elements.speed),r(this.elements.torrents),this.session_manager.addEventListener("session-change",this.update_from_session),this.update_from_session(),document.body.append(this.elements.root)}close(){if(!this.closed){this.outside.stop(),this.session_manager.removeEventListener("session-change",this.update_from_session),this.elements.root.remove(),this.dispatchEvent(new Event("close"));for(let e of Object.keys(this))this[e]=null;this.closed=!0}}};var ne=class n extends EventTarget{constructor(e){super(),this.options=e,this.options.trash=!1,this.elements=n._create(e),this.elements.dismiss.addEventListener("click",()=>this._onDismiss()),this.elements.confirm.addEventListener("click",()=>this._onConfirm()),document.body.append(this.elements.root),this.elements.dismiss.focus()}close(){if(!this.closed){this.elements.root.remove(),this.dispatchEvent(new Event("close"));for(let e of Object.keys(this))delete this[e];this.closed=!0}}_onDismiss(){this.close()}_onConfirm(){let{remote:e,torrents:t,trash:o}=this.options;t.length>0&&e.removeTorrents(t,o),this.close()}static _create(e){let{torrents:t}=e,o=X("remove-dialog"),{confirm:r,heading:s,message:i,workarea:a}=o;s.textContent=t.length===1?`Remove ${t[0].getName()}?`:`Remove ${t.length} transfers?`;let c=document.createElement("input");c.id="delete-local-data-check",c.type="checkbox",c.checked=!1,i.append(c);let l=document.createElement("label");l.id="delete-local-data-label",l.setAttribute("for",c.id),l.textContent="Delete downloaded data",i.append(l);let u=document.createElement("div"),d=g=>{g&&t.length===1?u.textContent="All data downloaded for this torrent will be deleted. Are you sure you want to remove it?":g?u.textContent="All data downloaded for these torrents will be deleted. Are you sure you want to remove them?":t.length===1?u.textContent="Once removed, continuing the transfer will require the torrent file. Are you sure you want to remove it?":u.textContent="Once removed, continuing the transfers will require the torrent files. Are you sure you want to remove them?",r.textContent=g?"Delete":"Remove"};return d(c.checked),c.addEventListener("click",()=>{e.trash=c.checked,d(c.checked)}),a.append(u),o}};var ae=class n extends EventTarget{constructor(e,t){super(),this.controller=e,this.remote=t,this.elements={},this.torrents=[],this.show()}show(){let e=this.controller.getSelectedTorrents();if(e.length!==1){console.trace();return}let{handler:t}=this.controller;this.torrents=e,this.elements=n._create(),this.elements.dismiss.addEventListener("click",()=>this._onDismiss()),this.elements.confirm.addEventListener("click",()=>this._onConfirm()),this.elements.entry.value=t===null?e[0].getName():t.subtree.name,document.body.append(this.elements.root),this.elements.entry.focus()}close(){let{handler:e}=this.controller;e&&e.classList.remove("selected"),this.elements.root.remove(),this.dispatchEvent(new Event("close")),delete this.remote,delete this.elements,delete this.torrents}_onDismiss(){this.close()}_onConfirm(){let{handler:e}=this.controller,[t]=this.torrents,o=e?e.file_path:t.getName(),r=this.elements.entry.value;this.remote.renameTorrent([t.getId()],o,r,s=>{if("result"in s){let i=s.result;if(e)if(e.subtree.name=i.name,b(e.name_container,i.name),e.subdir){let a=t.getIndividualFile(o);if(a){let c=a.name.slice(0,Math.max(0,a.name.lastIndexOf("/")+1));a.name=`${c}${i.name}`}}else t.refresh(i);else t.refresh(i)}else{let i=s.error,a=i.data?.errorString??i.message??"",c=new k({heading:`Error renaming "${o}"`,message:`${a} (${i.code}`});this.controller.setCurrentPopup(c)}delete this.controller}),this.close()}static _create(){let e=X("rename-dialog");e.root.setAttribute("aria-label","Rename Torrent"),e.heading.textContent="Enter new name:",e.confirm.textContent="Rename";let t=document.createElement("label");t.setAttribute("for","torrent-rename-name"),t.textContent="Enter new name:",e.workarea.append(t);let o=document.createElement("input");return o.setAttribute("type","text"),o.id="torrent-rename-name",e.entry=o,e.workarea.append(o),e}};var ce=class n extends EventTarget{constructor(e,t){super(),this.controller=e,this.remote=t,this.elements={},this.torrents=[],this.show()}show(){let e=this.controller.getSelectedTorrents();if(e.length===0){console.error("At least one selected torrent expected.");return}let[t]=e;this.torrents=e,this.elements=n._create(),this.elements.dismiss.addEventListener("click",()=>this._onDismiss()),this.elements.confirm.addEventListener("click",()=>this._onConfirm()),this.elements.entry.value=t.getLabels().join(", "),document.body.append(this.elements.root),this.elements.entry.focus()}close(){this.elements.root.remove(),this.dispatchEvent(new Event("close")),delete this.elements,delete this.torrents}_onDismiss(){this.close()}_onConfirm(){let{torrents:e}=this,{remote:t}=this,o=e.map(c=>c.getId()),{elements:r}=this,{entry:s}=r,{value:i}=s,a=i.split(",").map(c=>c.trim()).filter(c=>c.length>0);t.setLabels(o,a,c=>{if(c.result==="success")for(let l of e)l.refresh({labels:a})}),this.close()}static _create(){let e=X("labels-dialog");e.root.setAttribute("aria-label","Edit Labels"),e.heading.textContent="Edit Labels:",e.confirm.textContent="Save";let t=document.createElement("label");t.setAttribute("for","torrent-labels"),t.textContent="Labels:",e.workarea.append(t);let o=document.createElement("input");return o.setAttribute("type","text"),o.id="torrent-labels",e.entry=o,e.workarea.append(o),e}};var le=class n extends EventTarget{constructor(e){super(),this.elements=n._create(e),this.elements.dismiss.addEventListener("click",()=>this._onDismiss()),document.body.append(this.elements.root),this.elements.dismiss.focus()}close(){this.elements.root.remove(),this.dispatchEvent(new Event("close")),delete this.elements}_onDismiss(){this.close()}static _create(e){let t=X("shortcuts-dialog");t.root.setAttribute("aria-label","Keyboard Shortcuts");let o=document.createElement("table"),r=document.createElement("thead");o.append(r);let s=document.createElement("tr");r.append(s);let i=document.createElement("th");i.textContent="Key",s.append(i),i=document.createElement("th"),i.textContent="Action",s.append(i);let a=document.createElement("tbody");o.append(a);let c={};for(let[l,u]of e.allShortcuts().entries()){let d=l.split("+"),g=[d.pop(),...d].join("+");c[g]={name:u,shortcut:l}}for(let[,l]of Object.entries(c).toSorted()){let{name:u,shortcut:d}=l;s=document.createElement("tr"),a.append(s);let g=document.createElement("td");g.textContent=d.replaceAll("+"," + "),s.append(g),g=document.createElement("td"),g.textContent=e.text(u),s.append(g)}return t.heading.textContent="Transmission",t.dismiss.textContent="Close",t.heading.textContent="Keyboard shortcuts",t.message.append(o),t.confirm.remove(),delete t.confirm,t}};var de=class n extends EventTarget{constructor(e){super(),this.remote=e;let t=()=>this.remote.loadDaemonStats(r=>this._update(r.result)),o=5e3;this.interval=setInterval(t,o),t(),this.elements=n._create(),this.elements.dismiss.addEventListener("click",()=>this._onDismiss()),document.body.append(this.elements.root),this.elements.dismiss.focus()}close(){if(!this.closed){clearInterval(this.interval),this.elements.root.remove(),this.dispatchEvent(new Event("close"));for(let e of Object.keys(this))delete this[e];this.closed=!0}}_onDismiss(){this.close()}_update(e){console.log(e);let t=x,o=e["current-stats"],r=D.ratio(o.uploadedBytes,o.downloadedBytes);b(this.elements.session.up,t.size(o.uploadedBytes)),b(this.elements.session.down,t.size(o.downloadedBytes)),this.elements.session.ratio.innerHTML=t.ratioString(r),b(this.elements.session.time,t.timeInterval(o.secondsActive)),o=e["cumulative-stats"],r=D.ratio(o.uploadedBytes,o.downloadedBytes),b(this.elements.total.up,t.size(o.uploadedBytes)),b(this.elements.total.down,t.size(o.downloadedBytes)),this.elements.total.ratio.innerHTML=t.ratioString(r),b(this.elements.total.time,t.timeInterval(o.secondsActive))}static _create(){let e=X("statistics-dialog"),{confirm:t,dismiss:o,heading:r,root:s,workarea:i}=e;t.remove(),o.textContent="Close",delete e.confirm;let a="Statistics";s.setAttribute("aria-label",a),r.textContent=a;let c=["Uploaded:","Downloaded:","Ratio:","Running time:"],l=be("Current session",c),[u,d,g,m]=l.children,I=e.session={};I.up=u,I.down=d,I.ratio=g,I.time=m,i.append(l.root),l=be("Total",c);let[G,f,C,h]=l.children,y=e.total={};return y.up=G,y.down=f,y.ratio=C,y.time=h,i.append(l.root),e}};var F={formatETA:n=>{let e=n.getETA();return e<0||e>=999*60*60?"":`ETA: ${x.timeInterval(e,1)}`},formatLabels:(n,e)=>{let t=n.getLabels();e.innerHTML="";for(let o of t){let r=document.createElement("span");r.classList.add("torrent-label"),r.textContent=o,e.append(r)}},getProgressInfo:(n,e)=>{let t=e.getStatus(),o=["torrent-progress-bar"],r=100,s=null;if(t===A._StatusStopped&&o.push("paused"),e.needsMetaData())o.push("magnet"),r=e.getMetadataPercentComplete()*100;else if(t===A._StatusCheck)o.push("verify"),r=e.getRecheckProgress()*100;else if(e.getLeftUntilDone()>0)o.push("leech"),r=e.getPercentDone()*100;else if(o.push("seed"),t!==A._StatusStopped){let i=e.seedRatioLimit(n);s=i>0?e.getUploadRatio()*100/i:100}return e.isQueued()&&o.push("queued"),{classList:o,percent:r,ratio:s}},renderProgressbar:(n,e,t)=>{let o=F.getProgressInfo(n,e),r=Math.min(o.ratio||o.percent,100),s=`${x.percentString(r,2)}%`;t.className=o.classList.join(" "),t.style.setProperty("--progress",s),t.dataset.progress=o.ratio?"100%":s},symbol:{down:"\u25BC",up:"\u25B2"},updateIcon:(n,e)=>{n.dataset.iconMimeType=e.getPrimaryMimeType().split("/",1).pop(),n.dataset.iconMultifile=e.getFileCount()>1?"true":"false"}},ge=class n{static renderPeerDetails(e,t){let o=x,r=e.getError()!==A._ErrNone;t.classList.toggle("error",r);let s=e.getErrorMessage();if(s)b(t,s);else if(e.isDownloading()){let i=e.getPeersConnected(),a=e.getWebseedsSendingToUs(),c=["Downloading from"];i&&(c.push(e.getPeersSendingToUs(),"of",o.countString("peer","peers",i)),a&&c.push("and")),a&&c.push(o.countString("web seed","web seeds",a)),c.push("-",F.symbol.down,o.speedBps(e.getDownloadSpeed()),F.symbol.up,o.speedBps(e.getUploadSpeed())),b(t,c.join(" "))}else if(e.isSeeding()){let i=["Seeding to",e.getPeersGettingFromUs(),"of",o.countString("peer","peers",e.getPeersConnected()),"-",F.symbol.up,o.speedBps(e.getUploadSpeed())].join(" ");b(t,i)}else if(e.isChecking()){let i=["Verifying local data (",o.percentString(100*e.getRecheckProgress(),1),"% tested)"].join("");b(t,i)}else b(t,e.getStateString())}static renderProgressDetails(e,t,o){let r=x;if(t.needsMetaData()){let l="retrieving";t.isStopped()&&(l="needs");let u=100*t.getMetadataPercentComplete(),d=["Magnetized transfer - ",l," metadata (",r.percentString(u,1),"%)"].join("");b(o,d);return}let s=t.getSizeWhenDone(),i=t.getTotalSize(),a=t.isDone()||t.isSeeding(),c=[];if(a?(i===s?c.push(r.size(i)):c.push(r.size(s)," of ",r.size(t.getTotalSize())," (",t.getPercentDoneStr(),"%)"),c.push(", uploaded ",r.size(t.getUploadedEver())," (Ratio: ",r.ratioString(t.getUploadRatio()),")")):c.push(r.size(s-t.getLeftUntilDone())," of ",r.size(s)," (",t.getPercentDoneStr(),"%)"),!t.isStopped()&&(!a||t.seedRatioLimit(e)>0)){c.push(" - ");let l=t.getETA();l<0||l>=999*60*60?c.push("remaining time unknown"):c.push(r.timeInterval(t.getETA(),1)," remaining")}b(o,c.join(""))}render(e,t,o){let r=t.isStopped();o.classList.toggle("paused",r);let{labels:s,name:i,peer_details:a,progressbar:c,progress_details:l}=o;b(i,t.getName()),F.formatLabels(t,s),n.renderProgressDetails(e,t,l),F.renderProgressbar(e,t,c),n.renderPeerDetails(t,a)}createRow(e){let t=document.createElement("li");t.className="torrent";let o=[["icon","icon"],["name","torrent-name"],["labels","torrent-labels"],["progress_details","torrent-progress-details"],["progressbar","torrent-progress-bar"],["peer_details","torrent-peer-details"]];for(let[r,s]of o){let i=document.createElement("div");i.className=s,t.append(i),t[r]=i}return F.updateIcon(t.icon,e),t}},pe=class n{static renderPeerDetails(e,t){let o=x,r=e.getError()!==A._ErrNone;t.classList.toggle("error",r);let s=e.getErrorMessage();if(s)b(t,s);else if(e.isDownloading()){let i=e.getDownloadSpeed()>0,a=e.getUploadSpeed()>0;if(!a&&!i)b(t,"Idle");else{let c=[F.formatETA(e)];i&&c.push(F.symbol.down,o.speedBps(e.getDownloadSpeed())),a&&c.push(F.symbol.up,o.speedBps(e.getUploadSpeed())),b(t,c.join(" "))}}else if(e.isSeeding()){let i=["Ratio:",o.ratioString(e.getUploadRatio()),"-",F.symbol.up,o.speedBps(e.getUploadSpeed())].join(" ");b(t,i)}else b(t,e.getStateString())}render(e,t,o){o.classList.toggle("paused",t.isStopped());let{labels:r,name:s,peer_details:i,progressbar:a}=o;b(s,t.getName()),F.formatLabels(t,r),n.renderPeerDetails(t,i),F.renderProgressbar(e,t,a),a.classList.add("compact")}createRow(e){let t=document.createElement("li");t.className="torrent compact";let o=[["icon","icon"],["name","torrent-name compact"],["labels","torrent-labels compact"],["peer_details","torrent-peer-details compact"],["progressbar","torrent-progress-bar compact"]];for(let[r,s]of o){let i=document.createElement("div");i.className=s,t.append(i),t[r]=i}return F.updateIcon(t.icon,e),t}},ue=class{constructor(e,t,o){this._view=e,this._torrent=o,this._element=e.createRow(o);let r=()=>this.render(t);this._torrent.addEventListener("dataChanged",r),r()}getElement(){return this._element}render(e){let t=this.getTorrent();t&&this._view.render(e,t,this.getElement())}isSelected(){return this.getElement().classList.contains("selected")}getTorrent(){return this._torrent}getTorrentId(){return this.getTorrent().getId()}};var me=class n extends EventTarget{constructor(e,t,o){super(),this.action_manager=e,this.handler=null,this.notifications=t,this.prefs=o,this.remote=new J(this),this.speed={down:document.querySelector("#speed-down"),up:document.querySelector("#speed-up")};for(let[a,c]of[["#toolbar-open","open"],["#toolbar-delete","delete"],["#toolbar-start","start"],["#toolbar-pause","pause"],["#toolbar-inspector","inspector"],["#toolbar-overflow","overflow"]])document.querySelector(a).prepend(K[c](),document.createElement("BR"));document.querySelector(".speed-container").append(K.speedDown()),document.querySelector(".speed-container + .speed-container").append(K.speedUp()),this.addEventListener("torrent-selection-changed",a=>this.action_manager.update(a)),this.filterText="",this._torrents={},this._rows=[],this.oldTrackers=[],this.dirtyTorrents=new Set,this.changeStatus=!1,this.refilterSoon=Y(()=>this._refilter(!1)),this.refilterAllSoon=Y(()=>this._refilter(!0)),this.pointer_device=Object.seal({is_touch_device:"ontouchstart"in globalThis,long_press_callback:null,x:0,y:0}),this.popup=Array.from({length:n.max_popups}).fill(null),this.busytyping=!1;for(let a of document.querySelectorAll("button[data-action]")){let{action:c}=a.dataset;L(a,this.action_manager.isEnabled(c)),a.addEventListener("click",()=>{this.action_manager.click(c)})}document.querySelector("#filter-tracker").addEventListener("change",a=>{this.setFilterTracker(a.target.value)}),this.action_manager.addEventListener("change",a=>{for(let c of document.querySelectorAll(`[data-action="${a.action}"]`))L(c,a.enabled)}),this.action_manager.addEventListener("click",a=>{switch(a.action){case"copy-name":navigator.clipboard?navigator.clipboard.writeText(this.handler.subtree.name):prompt("Select all then copy",this.handler.subtree.name),this.handler.classList.remove("selected");break;case"deselect-all":this._deselectAll();break;case"move-bottom":this._moveBottom();break;case"move-down":this._moveDown();break;case"move-top":this._moveTop();break;case"move-up":this._moveUp();break;case"open-torrent":this.setCurrentPopup(new V(this,this.remote));break;case"pause-all-torrents":this._stopTorrents(this._getAllTorrents());break;case"pause-selected-torrents":this._stopTorrents(this.getSelectedTorrents());break;case"reannounce-selected-torrents":this._reannounceTorrents(this.getSelectedTorrents());break;case"remove-selected-torrents":this._removeSelectedTorrents();break;case"resume-selected-torrents":this._startSelectedTorrents(!1);break;case"resume-selected-torrents-now":this._startSelectedTorrents(!0);break;case"select-all":this._selectAll();break;case"show-about-dialog":this.setCurrentPopup(new ee(this.version_info));break;case"show-inspector":this.popup[0]instanceof E?this.popup[0].close():this.setCurrentPopup(new E(this),0);break;case"show-move-dialog":this.setCurrentPopup(new re(this,this.remote));break;case"show-overflow-menu":this.popup[n.default_popup_level]instanceof _?this.popup[n.default_popup_level].close():this.setCurrentPopup(new _(this,this.prefs,this.remote,this.action_manager));break;case"show-preferences-dialog":this.setCurrentPopup(new ie(this,this.remote),0);break;case"show-shortcuts-dialog":this.setCurrentPopup(new le(this.action_manager));break;case"show-statistics-dialog":this.setCurrentPopup(new de(this.remote));break;case"show-rename-dialog":this.setCurrentPopup(new ae(this,this.remote));break;case"show-labels-dialog":this.setCurrentPopup(new ce(this,this.remote));break;case"start-all-torrents":this._startTorrents(this._getAllTorrents());break;case"toggle-compact-rows":this.prefs.display_mode=this.prefs.display_mode===p.DisplayCompact?p.DisplayFull:p.DisplayCompact;break;case"verify-selected-torrents":this._verifyTorrents(this.getSelectedTorrents());break;default:console.warn(`unhandled action: ${a.action}`)}});let r=document.querySelector("#filter-mode");S(r,null,[["All",p.FilterAll]]),S(r,"status",[["Active",p.FilterActive],["Downloading",p.FilterDownloading],["Seeding",p.FilterSeeding],["Paused",p.FilterPaused],["Finished",p.FilterFinished],["Error",p.FilterError]]),S(r,"list",[["Private torrents",p.FilterPrivate],["Public torrents",p.FilterPublic]]),r.value=this.prefs.filter_mode,r.addEventListener("change",a=>{this.prefs.filter_mode=a.target.value,this.refilterAllSoon()}),r=document.querySelector("#filter-tracker"),S(r,null,[["All",p.FilterAll]]);let s=document.querySelector("#torrent-search");r=document.querySelector("#reset"),r.addEventListener("click",()=>{s.value="",this._setFilterText(s.value),this.refilterAllSoon()}),s.value.trim()&&(this.filterText=s.value,r.style.display="block",this.refilterAllSoon()),r=document.querySelector("#turtle"),r.addEventListener("click",a=>{this.remote.savePrefs({[B._TurtleState]:!a.target.classList.contains("alt-speed-enabled")})}),document.addEventListener("keydown",this._keyDown.bind(this)),document.addEventListener("keyup",this._keyUp.bind(this)),r=document.querySelector("#torrent-container"),r.addEventListener("click",a=>{this.popup[n.default_popup_level]&&this.setCurrentPopup(null),a.target===a.currentTarget&&this._deselectAll()}),r.addEventListener("dblclick",()=>{(!this.popup[0]||this.popup[0].name!=="inspector")&&this.action_manager.click("show-inspector")}),r.addEventListener("dragenter",n._dragenter),r.addEventListener("dragover",n._dragenter),r.addEventListener("drop",this._drop.bind(this)),this._setupSearchBox(),this.elements={torrent_list:document.querySelector("#torrent-list")};let i=a=>{let c=a.target;for(;c&&!c.classList.contains("torrent");)c=c.parentNode;let l=this._rows.find(u=>u.getElement()===c);l&&!l.isSelected()&&this._setSelectedRow(l),this.handler&&(this.handler.classList.remove("selected"),this.handler=null),this.context_menu("#torrent-container"),a.preventDefault()};this.pointer_event(this.elements.torrent_list,i),this.loadDaemonPrefs(),this._initializeTorrents(),this.refreshTorrents(),this.togglePeriodicSessionRefresh(!0),this.prefs.addEventListener("change",({key:a,value:c})=>this._onPrefChanged(a,c));for(let[a,c]of this.prefs.entries())this._onPrefChanged(a,c)}_openTorrentFromUrl(){setTimeout(()=>{let e=new URLSearchParams(globalThis.location.search).get("addtorrent");if(e){this.setCurrentPopup(new V(this,this.remote,e));let t=new URL(globalThis.location);t.search="",globalThis.history.pushState("","",t.toString())}},0)}loadDaemonPrefs(){this.remote.loadDaemonPrefs(e=>{this.session_properties=e.result,this._openTorrentFromUrl()})}get session_properties(){return this._session_properties}set session_properties(e){if(P(this._session_properties,e))return;this._session_properties=Object.seal(e);let t=new Event("session-change");t.session_properties=e,this.dispatchEvent(t),this._updateGuiFromSession(e)}_setupSearchBox(){let e=document.querySelector("#torrent-search"),t="blur";e.classList.add(t),e.addEventListener("blur",()=>e.classList.add(t)),e.addEventListener("focus",()=>e.classList.remove(t)),e.addEventListener("input",()=>{e.value.trim()!==this.filterText&&this._setFilterText(e.value)})}_onPrefChanged(e,t){switch(e){case p.DisplayMode:{this.torrentRenderer=t==="compact"?new pe:new ge,this.refilterAllSoon();break}case p.ContrastMode:{document.body.classList.remove("contrast-more","contrast-less"),document.body.classList.add(`contrast-${t}`);break}case p.FilterMode:case p.SortDirection:case p.SortMode:this.refilterAllSoon();break;case p.RefreshRate:{clearInterval(this.refreshTorrentsInterval);let o=this.refreshTorrents.bind(this),r=this.prefs.refresh_rate_sec,s=r>0?r*1e3:1e3;this.refreshTorrentsInterval=setInterval(o,s);break}default:break}}context_menu(e,t){let o=new te(this,t);this.setCurrentPopup(o);let r=document.querySelector(e).getBoundingClientRect(),s=Math.min(this.pointer_device.x,r.right+globalThis.scrollX-o.root.clientWidth),i=Math.min(this.pointer_device.y,r.bottom+globalThis.scrollY-o.root.clientHeight);o.root.style.left=`${Math.max(s,0)}px`,o.root.style.top=`${Math.max(i,0)}px`}pointer_event(e,t){if(this.pointer_device.is_touch_device){let o=this.pointer_device;e.addEventListener("touchstart",r=>{o.x=r.touches[0].pageX,o.y=r.touches[0].pageY,o.long_press_callback?(clearTimeout(o.long_press_callback),o.long_press_callback=null):o.long_press_callback=setTimeout(()=>{r.touches.length===1&&t(r)},500)}),e.addEventListener("touchend",()=>{clearTimeout(o.long_press_callback),o.long_press_callback=null,setTimeout(()=>{let r=this.popup[n.default_popup_level];r&&(r.root.style.pointerEvents="auto")},1)}),e.addEventListener("touchmove",r=>{o.x=r.touches[0].pageX,o.y=r.touches[0].pageY,clearTimeout(o.long_press_callback),o.long_press_callback=null}),e.addEventListener("contextmenu",r=>{r.preventDefault()})}else e.addEventListener("mousemove",o=>{this.pointer_device.x=o.pageX,this.pointer_device.y=o.pageY}),e.addEventListener("contextmenu",o=>{t(o);let r=this.popup[n.default_popup_level];r&&(r.root.style.pointerEvents="auto")})}static get max_popups(){return 2}static get default_popup_level(){return n.max_popups-1}_getAllTorrents(){return Object.values(this._torrents)}static _getTorrentIds(e){return e.map(t=>t.getId())}seedRatioLimit(){let e=this.session_properties;return e&&e.seedRatioLimited?e.seedRatioLimit:-1}_getSelectedRows(){return this._rows.filter(e=>e.isSelected())}getSelectedTorrents(){return this._getSelectedRows().map(e=>e.getTorrent())}_getSelectedTorrentIds(){return n._getTorrentIds(this.getSelectedTorrents())}_setSelectedRow(e){let t=e?e.getElement():null;for(let o of this.elements.torrent_list.children)o.classList.toggle("selected",o===t);this._dispatchSelectionChanged()}_selectRow(e){e.getElement().classList.add("selected"),this._dispatchSelectionChanged()}_deselectRow(e){e.getElement().classList.remove("selected"),this._dispatchSelectionChanged()}_selectAll(){for(let e of this.elements.torrent_list.children)e.classList.add("selected");this._dispatchSelectionChanged()}_deselectAll(){for(let e of this.elements.torrent_list.children)e.classList.remove("selected");this._dispatchSelectionChanged(),delete this._last_torrent_clicked}_indexOfLastTorrent(){return this._rows.findIndex(e=>e.getTorrentId()===this._last_torrent_clicked)}_selectRange(e){let t=this._indexOfLastTorrent();if(t===-1)this._selectRow(e);else{let o=this._rows.indexOf(e),r=Math.min(t,o),s=Math.max(t,o);for(let i=r;i<=s;++i)this._selectRow(this._rows[i])}this._dispatchSelectionChanged()}_dispatchSelectionChanged(){let e=[],t=[];for(let r of this._rows)(r.isSelected()?t:e).push(r.getTorrent());let o=new Event("torrent-selection-changed");o.nonselected=e,o.selected=t,this.dispatchEvent(o)}static _createKeyShortcutFromKeyboardEvent(e){let t=[];return e.ctrlKey&&t.push("Control"),e.altKey&&t.push("Alt"),e.metaKey&&t.push("Meta"),e.shiftKey&&t.push("Shift"),t.push(e.key.length===1?e.key.toUpperCase():e.key),t.join("+")}_keyDown(e){let{ctrlKey:t,keyCode:o,metaKey:r,shiftKey:s,target:i}=e,a=["INPUT","TEXTAREA"].includes(i.tagName);if(!a){let d=n._createKeyShortcutFromKeyboardEvent(e),g=this.action_manager.getActionForShortcut(d);if(g){e.preventDefault(),this.action_manager.click(g);return}}if(o===27&&this.popup.some(Boolean)){this.setCurrentPopup(null,0),e.preventDefault();return}let l=document.querySelector(".popup:not(.hidden)"),u=this._rows;if(!a&&!l&&!r&&!t){let d=o===16,g=o===38,m=o===40;if((g||m)&&u.length>0){let I=this._indexOfLastTorrent(),G=this._shift_index,f=0,C=u.length-1,h=I;m&&h+1<=C?++h:g&&h-1>=f&&--h;let y=u[h];G>=0?G<=I&&I=I&&I>h?this._selectRow(y):(G>=I&&h>I||G<=I&&I>h)&&this._deselectRow(u[I]):s?this._selectRange(y):this._setSelectedRow(y),y&&(this._last_torrent_clicked=y.getTorrentId(),y.getElement().scrollIntoView(),e.preventDefault())}else d&&(this._shift_index=this._indexOfLastTorrent())}}_keyUp(e){e.keyCode===16&&delete this._shift_index}static _dragenter(e){if(e.dataTransfer&&e.dataTransfer.types){let t=new Set(["text/uri-list","text/plain"]);if(e.dataTransfer.types.some(o=>t.has(o))||e.dataTransfer.types.includes("Files"))return e.stopPropagation(),e.preventDefault(),e.dataTransfer.dropEffect="copy",!1}else e.dataTransfer&&(e.dataTransfer.dropEffect="none");return!0}static _isValidURL(e){try{return!!new URL(e)}catch{return!1}}shouldAddedTorrentsStart(){return this.session_properties["start-added-torrents"]}_drop(e){let t=!this.shouldAddedTorrentsStart();if(!e.dataTransfer||!e.dataTransfer.types)return!0;let o=e.dataTransfer.types.findLast(s=>["text/uri-list","text/plain"].includes(s));for(let s of e.dataTransfer.getData(o).split(` -`).map(i=>i.trim()).filter(i=>n._isValidURL(i)))this.remote.addTorrentByUrl(s,t);let{files:r}=e.dataTransfer;return r.length>0&&this.setCurrentPopup(new V(this,this.remote,"",r)),e.preventDefault(),!1}togglePeriodicSessionRefresh(e){!e&&this.sessionInterval&&(clearInterval(this.sessionInterval),delete this.sessionInterval),e&&(this.loadDaemonPrefs(),this.sessionInterval||(this.sessionInterval=setInterval(this.loadDaemonPrefs.bind(this),8e3)))}_setFilterText(e){clearTimeout(this.busytyping),this.busytyping=setTimeout(()=>{this.busytyping=!1,this.filterText=e.trim(),this.refilterAllSoon()},e?250:0)}_onTorrentChanged(e){this.changeStatus&&(this._dispatchSelectionChanged(),this.changeStatus=!1);let t=e.currentTarget;this.dirtyTorrents.add(t.getId()),this.refilterSoon()}updateTorrents(e,t){this.remote.updateTorrents(e,t,(o,r)=>{let s=[],i=o.shift(),a={};for(let c of o){for(let[d,g]of i.entries())a[g]=c[d];let{id:l}=a,u=this._torrents[l];if(u){let d=u.needsMetaData();u.refresh(a),d&&!u.needsMetaData()&&s.push(l)}else u=this._torrents[l]=new A(a),u.addEventListener("dataChanged",this._onTorrentChanged.bind(this)),this.dirtyTorrents.add(l),(!("name"in u.fields)||!("status"in u.fields))&&s.push(l)}if(s.length>0){let c=["id",...A.Fields.Metadata,...A.Fields.Stats];this.updateTorrents(s,c),this.refilterSoon()}r&&(this._deleteTorrents(r),this.refilterSoon())})}refreshTorrents(){let e=["id",...A.Fields.Stats];this.updateTorrents("recently-active",e)}_initializeTorrents(){let e=["id",...A.Fields.Metadata,...A.Fields.Stats];this.updateTorrents(null,e)}_onRowClicked(e){let t=e.metaKey||e.ctrlKey,{row:o}=e.currentTarget;this.popup[n.default_popup_level]&&this.setCurrentPopup(null),e.stopPropagation(),e.shiftKey?(this._selectRange(o),globalThis.focus()):!o.isSelected()&&t?this._selectRow(o):o.isSelected()?o.isSelected()&&t?this._deselectRow(o):o.isSelected()&&this._setSelectedRow(o):this._setSelectedRow(o),this._last_torrent_clicked=o.getTorrentId()}_deleteTorrents(e){if(e&&e.length>0){for(let t of e)this.dirtyTorrents.add(t),delete this._torrents[t];this.refilterSoon()}}_removeSelectedTorrents(){let e=this.getSelectedTorrents();e.length>0&&this.setCurrentPopup(new ne({remote:this.remote,torrents:e}))}_startSelectedTorrents(e){this._startTorrents(this.getSelectedTorrents(),e)}_startTorrents(e,t){this.changeStatus=!0,this.remote.startTorrents(n._getTorrentIds(e),t,this.refreshTorrents,this)}_verifyTorrents(e){this.remote.verifyTorrents(n._getTorrentIds(e),this.refreshTorrents,this)}_reannounceTorrents(e){this.remote.reannounceTorrents(n._getTorrentIds(e),this.refreshTorrents,this)}_stopTorrents(e){this.changeStatus=!0,this.remote.stopTorrents(n._getTorrentIds(e),()=>{setTimeout(()=>{this.refreshTorrents()},500)},this)}changeFileCommand(e,t,o){this.remote.changeFileCommand(e,t,o)}_moveTop(){this.remote.moveTorrentsToTop(this._getSelectedTorrentIds(),this.refreshTorrents,this)}_moveUp(){this.remote.moveTorrentsUp(this._getSelectedTorrentIds(),this.refreshTorrents,this)}_moveDown(){this.remote.moveTorrentsDown(this._getSelectedTorrentIds(),this.refreshTorrents,this)}_moveBottom(){this.remote.moveTorrentsToBottom(this._getSelectedTorrentIds(),this.refreshTorrents,this)}_updateGuiFromSession(e){let[,t,o]=e.version.match(/^(.*)\s\(([\da-f]+)\)/);this.version_info={checksum:o,version:t},document.querySelector("#turtle").classList.toggle("alt-speed-enabled",e[B._TurtleState])}_updateStatusbar(){let e=x,t=this._getAllTorrents(),o=t.reduce((i,a)=>i+a.getUploadSpeed(),0),r=t.reduce((i,a)=>i+a.getDownloadSpeed(),0),s=e.countString("Transfer","Transfers",this._rows.length);b(this.speed.down,e.speedBps(r)),b(this.speed.up,e.speedBps(o)),b(document.querySelector("#filter-count"),s)}static _displayName(e){let t=e;return t.length>0&&(t=t.charAt(0).toUpperCase()+t.slice(1)),t}_updateFilterSelect(){let e=this._getTrackerCounts(),t=Object.keys(e).toSorted();if(t.length!==this.oldTrackers.length||t.some((o,r)=>o!==this.oldTrackers[r])){this.oldTrackers=t;let o=[["All",p.FilterAll,!this.filterTracker],...t.map(s=>[n._displayName(s),s,s===this.filterTracker])],r=document.querySelector("#filter-tracker");for(;r.firstChild;)r.lastChild.remove();S(r,null,o)}}sortRows(e){let t=e.map(r=>r.getTorrent()),o=e.reduce((r,s)=>(r[s.getTorrent().getId()]=s,r),{});A.sortTorrents(t,this.prefs.sort_mode,this.prefs.sort_direction);for(let[r,s]of t.entries())e[r]=o[s.getId()]}_refilter(e){let{sort_mode:t,sort_direction:o,filter_mode:r}=this.prefs,s=this.filterTracker,i=this.torrentRenderer,a=this.elements.torrent_list,c=null,l=null,u=/^labels:([\w,-\s]*)(.*)$/.exec(this.filterText);u?(c=u[2].trim(),l=u[1].split(",")):(c=this.filterText,l=[]);let d=()=>[...a.children].length,g=()=>[...a.children].reduce((Z,w)=>Z+w.classList.contains("selected")?1:0,0),m=d(),I=g();if(this._updateFilterSelect(),e){for(;a.firstChild;)a.firstChild.remove();this._rows=[],this.dirtyTorrents=new Set(Object.keys(this._torrents)),document.querySelector("#reset").style.display=this.filterText.length>0?"block":"none"}let G=[],f=[];for(let Z of this._rows)this.dirtyTorrents.has(Z.getTorrentId())?f.push(Z):G.push(Z);for(let Z of f)Z.getElement().remove();let C=[];for(let Z of f){let w=Z.getTorrentId(),Q=this._torrents[w];Q&&Q.test(r,s,c,l)&&C.push(Z),this.dirtyTorrents.delete(w)}f=C;for(let Z of this.dirtyTorrents.values()){let w=this._torrents[Z];if(w&&w.test(r,s,c,l)){let Q=new ue(i,this,w),he=Q.getElement();he.row=Q,f.push(Q),he.addEventListener("click",this._onRowClicked.bind(this))}}this.sortRows(f);let h=[],y=G.length,U=f.length,H=document.createDocumentFragment(),O=0,z=0;for(;O!==y||z!==U;){let Z=null;if(O===y?Z=!1:z===U?Z=!0:Z=A.compareTorrents(G[O].getTorrent(),f[z].getTorrent(),t,o)<0,Z)h.push(G[O++]);else{let w=f[z++],Q=w.getElement();O===y?H.append(Q):a.insertBefore(Q,G[O].getElement()),h.push(w)}}a.append(H),this._rows=h,this.dirtyTorrents.clear(),this._updateStatusbar(),(I!==g()||m!==d())&&this._dispatchSelectionChanged()}setFilterTracker(e){let t=document.querySelector("#filter-tracker");t.value=e,this.filterTracker=e===p.FilterAll?"":e,this.refilterAllSoon()}_getTrackerCounts(){let e={};for(let t of this._getAllTorrents())for(let o of t.getTrackers()){let{sitename:r}=o;e[r]=(e[r]||0)+1}return e}setCurrentPopup(e,t=n.default_popup_level){for(let o=t;o{this.popup[t]&&(this.popup[t].removeEventListener("close",o),this.popup[t]=null)};this.popup[t].addEventListener("close",o)}else this.handler&&this.handler.classList.remove("selected")}};function _e(){let n=new j,e=new p,t=new q(e),o=new me(n,t,e),r=Y(()=>o.elements.torrent_list.scrollTo(0,1));globalThis.addEventListener("load",r),globalThis.addEventListener("orientationchange",r)}document.addEventListener("DOMContentLoaded",_e);})(); +(()=>{var ve=Object.create;var Ce=Object.defineProperty;var Xe=Object.getOwnPropertyDescriptor;var Ze=Object.getOwnPropertyNames;var Fe=Object.getPrototypeOf,we=Object.prototype.hasOwnProperty;var Le=(n,e)=>()=>(e||n((e={exports:{}}).exports,e),e.exports);var We=(n,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Ze(e))!we.call(n,r)&&r!==t&&Ce(n,r,{get:()=>e[r],enumerable:!(o=Xe(e,r))||o.enumerable});return n};var Qe=(n,e,t)=>(t=n!=null?ve(Fe(n)):{},We(e||!n||!n.__esModule?Ce(t,"default",{value:n,enumerable:!0}):t,n));var fe=Le((je,Ae)=>{"use strict";Ae.exports=function n(e,t){if(e===t)return!0;if(e&&t&&typeof e=="object"&&typeof t=="object"){if(e.constructor!==t.constructor)return!1;var o,r,s;if(Array.isArray(e)){if(o=e.length,o!=t.length)return!1;for(r=o;r--!==0;)if(!n(e[r],t[r]))return!1;return!0}if(e instanceof Map&&t instanceof Map){if(e.size!==t.size)return!1;for(r of e.entries())if(!t.has(r[0]))return!1;for(r of e.entries())if(!n(r[1],t.get(r[0])))return!1;return!0}if(e instanceof Set&&t instanceof Set){if(e.size!==t.size)return!1;for(r of e.entries())if(!t.has(r[0]))return!1;return!0}if(ArrayBuffer.isView(e)&&ArrayBuffer.isView(t)){if(o=e.length,o!=t.length)return!1;for(r=o;r--!==0;)if(e[r]!==t[r])return!1;return!0}if(e.constructor===RegExp)return e.source===t.source&&e.flags===t.flags;if(e.valueOf!==Object.prototype.valueOf)return e.valueOf()===t.valueOf();if(e.toString!==Object.prototype.toString)return e.toString()===t.toString();if(s=Object.keys(e),o=s.length,o!==Object.keys(t).length)return!1;for(r=o;r--!==0;)if(!Object.prototype.hasOwnProperty.call(t,s[r]))return!1;for(r=o;r--!==0;){var i=s[r];if(!n(e[i],t[i]))return!1}return!0}return e!==e&&t!==t}});var j=class n extends EventTarget{constructor(){super(),this.actions=Object.seal({"copy-name":{enabled:!0,text:"Copy name"},"deselect-all":{enabled:!1,shortcut:"D",text:"Deselect all"},"move-bottom":{enabled:!1,text:"Bottom"},"move-down":{enabled:!1,text:"Down"},"move-top":{enabled:!1,text:"Top"},"move-up":{enabled:!1,text:"Up"},"open-torrent":{enabled:!0,shortcut:"O",text:"Open torrent\u2026"},"pause-all-torrents":{enabled:!1,text:"Pause all"},"pause-selected-torrents":{enabled:!1,shortcut:"U",text:"Pause"},"reannounce-selected-torrents":{enabled:!1,text:"Ask tracker for more peers"},"remove-selected-torrents":{enabled:!1,text:"Remove selected torrents"},"resume-selected-torrents":{enabled:!1,shortcut:"R",text:"Resume"},"resume-selected-torrents-now":{enabled:!1,text:"Resume now"},"select-all":{enabled:!1,shortcut:"A",text:"Select all"},"show-about-dialog":{enabled:!0,text:"About"},"show-inspector":{enabled:!1,shortcut:"I",text:"Torrent Inspector"},"show-labels-dialog":{enabled:!1,shortcut:"K",text:"Edit Labels\u2026"},"show-move-dialog":{enabled:!1,shortcut:"L",text:"Set location\u2026"},"show-overflow-menu":{enabled:!0,text:"More options\u2026"},"show-preferences-dialog":{enabled:!0,shortcut:"P",text:"Edit preferences"},"show-rename-dialog":{enabled:!1,shortcut:"N",text:"Rename\u2026"},"show-shortcuts-dialog":{enabled:!0,text:"Keyboard shortcuts"},"show-statistics-dialog":{enabled:!0,shortcut:"S",text:"Statistics"},"start-all-torrents":{enabled:!1,text:"Start all"},"toggle-compact-rows":{enabled:!0,text:"Compact rows"},"toggle-contrast":{enabled:!0,text:"High contrast UI"},"verify-selected-torrents":{enabled:!1,shortcut:"V",text:"Verify local data"}})}click(e){if(this.isEnabled(e)){let t=new Event("click");t.action=e,this.dispatchEvent(t)}}getActionForShortcut(e){for(let[t,o]of Object.entries(this.actions))if(e===o.shortcut)return t;return null}allShortcuts(){return new Map(Object.entries(this.actions).filter(([,e])=>e.shortcut).map(([e,t])=>[t.shortcut,e]))}isEnabled(e){return this._getAction(e).enabled}text(e){return this._getAction(e).text}keyshortcuts(e){return this._getAction(e).shortcut}update(e){let t=n._recount(e.selected,e.nonselected);this._updateStates(t)}_getAction(e){let t=this.actions[e];if(!t)throw new Error(`no such action: ${e}`);return t}static _recount(e,t){let o=e.length+t.length,r=e.filter(d=>d.isStopped()).length,s=e.length-r,i=t.filter(d=>d.isStopped()).length,a=t.length-i,c=r+i,l=s+a,u=e.filter(d=>d.isQueued()).length;return{active:l,nonselected_active:a,nonselected_paused:i,paused:c,selected:e.length,selected_active:s,selected_paused:r,selected_queued:u,total:o}}_updateStates(e){let t=(o,r)=>{for(let s of r)this._updateActionState(s,o)};t(e.selected_paused>0,["resume-selected-torrents"]),t(e.paused>0,["start-all-torrents"]),t(e.active>0,["pause-all-torrents"]),t(e.selected_paused>0||e.selected_queued>0,["resume-selected-torrents-now"]),t(e.selected_active>0,["pause-selected-torrents","reannounce-selected-torrents"]),t(e.selected>0,["deselect-all","move-bottom","move-down","move-top","move-up","remove-selected-torrents","show-inspector","show-labels-dialog","show-move-dialog","verify-selected-torrents"]),t(e.selected===1,["show-rename-dialog"]),t(e.selectedUe(r,d,i,l,t))}return a[0].classList.add("selected"),i.children[0].classList.remove("hidden"),{buttons:a,dismiss:s,root:o}}function X(n){let e=document.createElement("dialog");e.classList.add("dialog-container","popup",n),e.open=!0,e.setAttribute("role","dialog");let t=document.createElement("div");t.classList.add("dialog-window"),e.append(t);let o=document.createElement("div");o.classList.add("dialog-logo"),t.append(o);let r=document.createElement("div");r.classList.add("dialog-heading"),t.append(r);let s=document.createElement("div");s.classList.add("dialog-message"),t.append(s);let i=document.createElement("div");i.classList.add("dialog-workarea"),t.append(i);let a=document.createElement("div");a.classList.add("dialog-buttons"),t.append(a);let c=document.createElement("span");c.className="flexible-space",a.append(c);let l=document.createElement("button");l.classList.add("dialog-dismiss-button"),l.textContent="Cancel",a.append(l);let u=document.createElement("button");return u.textContent="OK",a.append(u),t.addEventListener("keyup",({key:d})=>{d==="Enter"&&u.click()}),{confirm:u,dismiss:l,heading:r,message:s,root:e,workarea:i}}function v(){return typeof crypto.randomUUID=="function"?crypto.randomUUID():("10000000-1000-4000-8000"+-1e11).replaceAll(/[018]/g,n=>(n^crypto.getRandomValues(new Uint8Array(1))[0]&15>>n/4).toString(16))}function N(n,e,t){let o=t.map(r=>new Option(...r));if(e){let r=document.createElement("OPTGROUP");r.label=e,r.append(...o),n.append(r)}else n.append(...o)}var K=Object.freeze({delete:()=>T(["path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2L21 6L3 6"}],["line",{x1:10,x2:10,y1:11,y2:17}],["line",{x1:14,x2:14,y1:11,y2:17}]),inspector:()=>{let n=Y("svg",{fill:"none","fill-opacity":1,height:26,stroke:"currentColor",viewBox:"-1 -1 26 26",width:26}),e=Y("g",{});return e.append(Y("circle",{cx:12,cy:12,r:11,"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":2}),Y("path",{d:"M 11.88208 4.883789 C 12.326418 4.883789 12.702391 5.039305 13.01001 5.350342 C 13.317628 5.6613785 13.471436 6.035642 13.471436 6.4731445 C 13.471436 6.910647 13.31592 7.283202 13.004883 7.59082 C 12.693846 7.898439 12.319582 8.052246 11.88208 8.052246 C 11.444578 8.052246 11.072023 7.898439 10.764404 7.59082 C 10.456786 7.283202 10.302979 6.910647 10.302979 6.4731445 C 10.302979 6.035642 10.456786 5.6613785 10.764404 5.350342 C 11.072023 5.039305 11.444578 4.883789 11.88208 4.883789 Z M 13.317627 9.528809 L 13.317627 17.126953 C 13.317627 17.803714 13.39624 18.236083 13.553467 18.424072 C 13.710694 18.612061 14.018308 18.719726 14.476318 18.74707 L 14.476318 19.11621 L 9.298096 19.11621 L 9.298096 18.74707 C 9.721926 18.733398 10.036376 18.610353 10.241455 18.37793 C 10.378175 18.220702 10.446533 17.803714 10.446533 17.126953 L 10.446533 11.52832 C 10.446533 10.851559 10.367921 10.41919 10.210693 10.231201 C 10.053466 10.043212 9.74927 9.935547 9.298096 9.908203 L 9.298096 9.528809 Z",fill:"currentColor"})),n.append(e),n},open:()=>T(["path",{d:"M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"}],["line",{x1:12,x2:12,y1:11,y2:17}],["line",{x1:9,x2:15,y1:14,y2:14}]),overflow:()=>T(["line",{x1:3,x2:21,y1:12,y2:12}],["line",{x1:3,x2:21,y1:6,y2:6}],["line",{x1:3,x2:21,y1:18,y2:18}]),pause:()=>T(["rect",{height:16,width:4,x:6,y:4}],["rect",{height:16,width:4,x:14,y:4}]),speedDown:()=>T(["polyline",{points:"6 9 12 15 18 9"}]),speedUp:()=>T(["polyline",{points:"18 15 12 9 6 15"}]),start:()=>T(["polyline",{points:"5 3 19 12 5 21 5 3"}])});function Oe(n){let e=document.createElement("fieldset");e.classList.add("section");let t=document.createElement("legend");t.classList.add("title"),t.textContent=n,e.append(t);let o=document.createElement("div");return o.classList.add("content"),e.append(o),{content:o,root:e}}function be(n,e){let t=[],{root:o,content:r}=Oe(n);for(let s of e){let i=document.createElement("label");i.textContent=s,r.append(i);let a=document.createElement("div");a.id=v(),r.append(a),i.setAttribute("for",a.id),t.push(a)}return{children:t,root:o}}function R(n,e=100){let t=null;return(...o)=>{t||(t=setTimeout(()=>{t=null,n(...o)},e))}}function P(n,e){return(0,Be.default)(n,e)}function _e(n,e,t){t?n.setAttribute(e,!0):n.removeAttribute(e)}function w(n,e){_e(n,"disabled",!e)}function $(n,e){n.classList.toggle("checked",e)}var _=class extends EventTarget{constructor(e){super(),this.listener=t=>{e.contains(t.target)||(this.dispatchEvent(new MouseEvent(t.type,t)),t.preventDefault())},Object.seal(this),this.start()}start(){setTimeout(()=>document.addEventListener("click",this.listener),0)}stop(){document.removeEventListener("click",this.listener)}};function b(n,e){n.textContent!==e&&(n.textContent=e)}var q=class{constructor(e){this._prefs=e,this._elements={toggle:document.querySelector("#toggle-notifications")}}_setEnabled(e){this.prefs.notifications_enabled=e,b(this._toggle,`${e?"Disable":"Enable"} Notifications`)}_requestPermission(){Notification.requestPermission().then(e=>this._setEnabled(e==="granted"))}toggle(){this._enabled?this._setEnabled(!1):Notification.permission==="granted"?this._setEnabled(!0):Notification.permission!=="denied"&&this._requestPermission()}};var p=class n extends EventTarget{constructor(){super(),this._cache={},this.dispatchPrefsChange=R((e,t,o)=>{let r=new Event("change");Object.assign(r,{key:e,old_value:t,value:o}),this.dispatchEvent(r)});for(let[e,t]of Object.entries(n._Defaults))this._set(e,n._getCookie(e,t)),Object.defineProperty(this,e.replaceAll("-","_"),{get:()=>this._get(e),set:o=>{this._set(e,o)}});Object.seal(this)}entries(){return Object.entries(this._cache)}keys(){return Object.keys(this._cache)}_get(e){let{_cache:t}=this;if(!Object.prototype.hasOwnProperty.call(t,e))throw new Error(e);return t[e]}_set(e,t){let{_cache:o}=this,r=o[e];r!==t&&(o[e]=t,n._setCookie(e,t),this.dispatchPrefsChange(e,r,t))}static _setCookie(e,t){let o=new Date;o.setFullYear(o.getFullYear()+1),document.cookie=`${e}=${t}; SameSite=Strict; expires=${o.toGMTString()}`}static _getCookie(e,t){let o=n._readCookie(e);if(o===null)return t;let r=typeof t;if(r==="boolean")return o==="true"?!0:o==="false"?!1:t;if(r==="number"){let s=Number.parseFloat(o);return Number.isNaN(s)?t:s}return o}static _readCookie(e){let o=`; ${document.cookie}`.split(`; ${e}=`);return o.length===2?o.pop().split(";").shift():null}};p.AltSpeedEnabled="alt-speed-enabled";p.DisplayCompact="compact";p.DisplayFull="full";p.DisplayMode="display-mode";p.ContrastLess="less";p.ContrastMore="more";p.ContrastMode="contrast-mode";p.FilterActive="active";p.FilterAll="all";p.FilterDownloading="downloading";p.FilterError="error";p.FilterFinished="finished";p.FilterMode="filter-mode";p.FilterPaused="paused";p.FilterPrivate="private";p.FilterPublic="public";p.FilterSeeding="seeding";p.NotificationsEnabled="notifications-enabled";p.RefreshRate="refresh-rate-sec";p.SortAscending="ascending";p.SortByActivity="activity";p.SortByAge="age";p.SortByName="name";p.SortByProgress="progress";p.SortByQueue="queue";p.SortByRatio="ratio";p.SortBySize="size";p.SortByState="state";p.SortDescending="descending";p.SortDirection="sort-direction";p.SortMode="sort-mode";p._Defaults={[p.AltSpeedEnabled]:!1,[p.DisplayMode]:p.DisplayFull,[p.ContrastMode]:globalThis.matchMedia("(prefers-contrast: more)").matches?p.ContrastMore:p.ContrastLess,[p.FilterMode]:p.FilterAll,[p.NotificationsEnabled]:!1,[p.RefreshRate]:5,[p.SortDirection]:p.SortAscending,[p.SortMode]:p.SortByName};var ee=class n extends EventTarget{constructor(e){super(),this.elements=n._create(e),this.elements.dismiss.addEventListener("click",()=>this.close()),document.body.append(this.elements.root),this.elements.dismiss.focus()}close(){this.elements.root.remove(),this.dispatchEvent(new Event("close")),delete this.elements}static _create(e){let t=X("about-dialog");t.root.setAttribute("aria-label","About transmission"),t.heading.textContent="Transmission",t.dismiss.textContent="Close";let o=document.createElement("div");return o.classList.add("about-dialog-version-number"),o.textContent=e.version,t.heading.append(o),o=document.createElement("div"),o.classList.add("about-dialog-version-checksum"),o.textContent=e.checksum,t.heading.append(o),o=document.createElement("div"),o.textContent="A fast and easy bitTorrent client",t.workarea.append(o),o=document.createElement("div"),o.textContent="Copyright \xA9 The Transmission Project",t.workarea.append(o),o=document.createElement("a"),o.href="https://transmissionbt.com/",o.target="_blank",o.textContent="https://transmissionbt.com/",t.workarea.append(o),t.confirm.remove(),delete t.confirm,t}};var te=class extends EventTarget{constructor(e,t){super(),this.action_listener=this._update.bind(this),this.controller=e,this.action_manager=e.action_manager,this.action_manager.addEventListener("change",this.action_listener),this.handler=e.handler,this.menu_items=t,Object.assign(this,this._create()),this.outside=new _(this.root),this.outside.addEventListener("click",()=>{this.handler&&this.handler.classList.remove("selected"),this.close()}),this.show()}show(){for(let[e,t]of Object.entries(this.actions))w(t,this.action_manager.isEnabled(e));document.body.append(this.root)}close(){if(!this.closed){this.outside.stop(),this.action_manager.removeEventListener("change",this.action_listener),this.root.remove(),this.dispatchEvent(new Event("close"));for(let e of Object.keys(this))delete this[e];this.closed=!0}}_update(e){let t=this.actions[e.action];t&&w(t,e.enabled)}_create(){let e=document.createElement("div");e.role="menu",e.classList.add("context-menu","popup"),e.addEventListener("contextmenu",i=>{i.preventDefault()}),e.style.pointerEvents="none";let t={},o=(i,a=!1)=>{let c=document.createElement("div"),l=this.action_manager.text(i);c.role="menuitem",a?c.classList.add("context-menuitem","warning"):c.classList.add("context-menuitem"),c.dataset.action=i,c.textContent=l;let u=this.action_manager.keyshortcuts(i);return u&&c.setAttribute("aria-keyshortcuts",u),c.addEventListener("click",()=>{this.action_manager.click(i),this.close()}),t[i]=c,c},r=()=>{let i=document.createElement("div");return i.classList.add("context-menu-separator"),i},s=(i,...a)=>{let c=document.createElement("div");c.className="context-menuitem",c.textContent=i;let l=document.createElement("div");l.className="arrow",c.append(l);let u=document.createElement("div");u.className="submenu",l.append(u);let d=document.createElement("div");return d.className="open right",u.append(d),d.append(...a.map(g=>o(g))),c.addEventListener("click",g=>{let m=c.lastChild.lastChild;if(!g.target.classList.contains("right")&&!g.target.parentNode.classList.contains("right")&&!g.target.classList.contains("left")&&!g.target.parentNode.classList.contains("left")&&m.style.display==="block"){m.style.display="none";return}for(let h of e.querySelectorAll(".submenu"))h.style.display="none";m.style.display="block";let I=c.getBoundingClientRect(),G=m.lastChild.getBoundingClientRect(),f=Math.min(0,document.documentElement.clientHeight-window.visualViewport.offsetTop-I.top-m.clientHeight+3),C=Math.min(0,document.documentElement.clientWidth-window.visualViewport.offsetLeft-I.right-m.clientWidth);m.style.top=`${f}px`,C?(m.lastChild.className="open left",m.style.left=`${-I.width-G.width}px`):(m.lastChild.className="open right",m.style.left=`${C}px`)}),c};if(this.menu_items)for(let i of this.menu_items)e.append(i?o(i):r());else e.append(o("resume-selected-torrents"),o("resume-selected-torrents-now"),o("pause-selected-torrents"),r(),s("Move in the queue","move-top","move-up","move-down","move-bottom"),r(),o("remove-selected-torrents",!0),r(),o("verify-selected-torrents"),o("show-move-dialog"),o("show-rename-dialog"),o("show-labels-dialog"),r(),o("reannounce-selected-torrents"),r(),s("Select operation","select-all","deselect-all"));return{actions:t,root:e}}};var ye=new Intl.PluralRules,W=ye.resolvedOptions().locale,Te=new Intl.NumberFormat(W),Ie=1e3,Re=[new Intl.NumberFormat(W,{maximumFractionDigits:0,style:"unit",unit:"byte"}),new Intl.NumberFormat(W,{maximumFractionDigits:0,style:"unit",unit:"kilobyte"}),new Intl.NumberFormat(W,{maximumFractionDigits:0,style:"unit",unit:"megabyte"}),new Intl.NumberFormat(W,{maximumFractionDigits:2,style:"unit",unit:"gigabyte"}),new Intl.NumberFormat(W,{maximumFractionDigits:2,style:"unit",unit:"terabyte"}),new Intl.NumberFormat(W,{maximumFractionDigits:2,style:"unit",unit:"petabyte"})],Ye=new Intl.NumberFormat(W,{maximumFractionDigits:2,style:"unit",unit:"kilobyte-per-second"}),Ne=new Intl.NumberFormat(W,{maximumFractionDigits:2,style:"unit",unit:"megabyte-per-second"}),Ve=new Intl.NumberFormat(W,{maximumFractionDigits:2,style:"unit",unit:"gigabyte-per-second"}),x={_toTruncFixed(n,e){return(Math.floor(n*10**e)/10**e).toFixed(e)},countString(n,e,t){return`${this.number(t)} ${this.ngettext(n,e,t)}`},mem(n){if(n<0)return"Unknown";if(n===0)return"None";let e=n;for(let t of Re){if(en.includes(e))?"\u2026":n},timeInterval(n,e=3){let t=Math.floor(n/86400),o=[];t&&o.push(this.countString("day","days",t));let r=Math.floor(n%86400/3600);(t||r)&&o.push(this.countString("hour","hours",r));let s=Math.floor(n%3600/60);return t||r||s?(o.push(this.countString("minute","minutes",s)),o=o.slice(0,e),o.length>1?`${o.slice(0,-1).join(", ")} and ${o.slice(-1)}`:o[0]):this.countString("second","seconds",Math.floor(n%60))},timestamp(n){if(!n)return"N/A";let e=new Date(n*1e3),t=new Date,o="",r="",s=t.getFullYear()===e.getFullYear(),i=t.getMonth()===e.getMonth(),a=t.getDate()-e.getDate();s&&i&&Math.abs(a)<=1?a===0?o="Today":a===1?o="Yesterday":o="Tomorrow":o=e.toDateString();let c=e.getHours(),l="AM";c>12&&(c=c-12,l="PM"),c===0&&(c=12),c<10&&(c=`0${c}`);let u=e.getMinutes();return u<10&&(u=`0${u}`),n=e.getSeconds(),n<10&&(n=`0${n}`),r=[c,u,n].join(":"),[o,r,l].join(" ")},toKBps(n){return Math.floor(n/Ie)}};var oe=class extends EventTarget{isDone(){return this.fields.have>=this.fields.size}isEditable(){return this.fields.torrent.getFileCount()>1&&!this.isDone()}refreshWantedHTML(){let e=this.elements.root;e.classList.toggle("skip",!this.fields.isWanted),e.classList.toggle("complete",this.isDone()),w(e.checkbox,this.isEditable()),e.checkbox.checked=this.fields.isWanted}refreshProgressHTML(){let{size:e,have:t}=this.fields,o=100*(e?t/e:1),r=x,s=`${r.size(t)} of ${r.size(e)} (${r.percentString(o,1)}%)`;b(this.elements.progress,s)}refresh(){let e=0,t=!1,o=!1,r=!1,s=0,i=!1,a=this.fields.torrent.getFiles();for(let c of this.fields.indices){let l=a[c];switch(e+=l.bytes_completed,s+=l.length,i|=l.wanted,l.priority.toString()){case"-1":o=!0;break;case"1":t=!0;break;default:r=!0;break}}$(this.elements.priority_low_button,o),$(this.elements.priority_normal_button,r),$(this.elements.priority_high_button,t),(this.fields.have!==e||this.fields.size!==s)&&(this.fields.have=e,this.fields.size=s,this.refreshProgressHTML()),this.fields.isWanted!==i&&(this.fields.isWanted=i,this.refreshWantedHTML())}fireWantedChanged(e){let t=new Event("wantedToggled");t.indices=[...this.fields.indices],t.wanted=e,this.dispatchEvent(t)}firePriorityChanged(e){let t=new Event("priorityToggled");t.indices=[...this.fields.indices],t.priority=e,this.dispatchEvent(t)}createRow(e,t){let o=document.createElement("li");o.classList.add("inspector-torrent-file-list-entry"),o.subtree=t,this.elements.root=o;let r=l=>{this.controller.handler&&this.controller.handler.classList.remove("selected"),setTimeout(()=>{o.classList.add("selected")},0);let u=t.name,d=t.parent;for(;d.name;){o.subdir=!0,u=`${d.name}/${u}`;let{parent:m}=d;d=m}o.file_path=u,this.controller.handler=o;let g=["show-rename-dialog",null,"copy-name"];this.controller.context_menu("#inspector",g),l.preventDefault()};this.controller.pointer_event(o,r);let s=document.createElement("input"),i=v();s.type="checkbox",s.className="file-wanted-control",s.title="Download file",s.id=i,s.addEventListener("change",l=>this.fireWantedChanged(l.target.checked)),o.checkbox=s,o.append(s),s=document.createElement("label"),s.className="inspector-torrent-file-list-entry-name",s.setAttribute("for",i),b(s,t.name),o.append(s),o.name_container=s,s=document.createElement("div"),s.className="inspector-torrent-file-list-entry-progress",o.append(s),this.elements.progress=s,s=document.createElement("div"),s.className="file-priority-radiobox";let a=s,c=l=>this.firePriorityChanged(l.target.value);s=document.createElement("input"),s.type="radio",s.value="-1",s.className="low",s.title="Low Priority",s.addEventListener("click",c),this.elements.priority_low_button=s,a.append(s),s=document.createElement("input"),s.type="radio",s.value="0",s.className="normal",s.title="Normal Priority",s.addEventListener("click",c),this.elements.priority_normal_button=s,a.append(s),s=document.createElement("input"),s.type="radio",s.value="1",s.title="High Priority",s.className="high",s.addEventListener("click",c),this.elements.priority_high_button=s,a.append(s),o.append(a),o.style.paddingLeft=`${t.depth*20}px`,this.refresh()}getElement(){return this.elements.root}constructor(e,t,o){super(),this.controller=e,this.fields={have:0,indices:o.file_indices,isWanted:!0,size:0,torrent:t},this.elements={priority_high_button:null,priority_low_button:null,priority_normal_button:null,progress:null,root:null},this.createRow(t,o)}};var A=class n extends EventTarget{constructor(e){super(),this.fieldObservers={},this.fields={},this.refresh(e),this.setLazyCollatedField("name","collatedName"),this.setLazyCollatedField("trackers","collatedTrackers")}setLazyCollatedField(e,t){this.notifyOnFieldChange(e,()=>delete this.fields[t])}notifyOnFieldChange(e,t){(this.fieldObservers[e]??=[]).push(t)}setField(e,t,o){let r=e[t];if(P(r,o))return!1;let s=this.fieldObservers[t];if(e===this.fields&&s&&s.length>0)for(let i of s)i.call(this,o,r,t);return e[t]=o,!0}updateFiles(e){let t=!1,o=this.fields.files||[],r=["length","name","bytes_completed","wanted","priority"];for(let[s,i]of e.entries()){let a=o[s]||{};for(let c of r)c in i&&(t|=this.setField(a,c,i[c]));o[s]=a}return this.fields.files=o,t}static collateTrackers(e){return e.map(t=>t.announce.toLowerCase()).join(" ")}refreshFields(e){let t=!1;for(let[o,r]of Object.entries(e))switch(o){case"files":case"file_stats":t|=this.updateFiles(r);break;case"tracker_stats":t|=this.setField(this.fields,"trackers",r);break;case"trackers":o in this.fields||(t|=this.setField(this.fields,o,r));break;default:t|=this.setField(this.fields,o,r)}return t}refresh(e){this.refreshFields(e)&&this.dispatchEvent(new Event("dataChanged"))}getIndividualFile(e){return this.fields.files.find(t=>t.name===e)}getComment(){return this.fields.comment}getCreator(){return this.fields.creator}getDateAdded(){return this.fields.added_date}getDateCreated(){return this.fields.date_created}getDesiredAvailable(){return this.fields.desired_available}getDownloadDir(){return this.fields.download_dir}getDownloadSpeed(){return this.fields.rate_download}getDownloadedEver(){return this.fields.downloaded_ever}getError(){return this.fields.error}getErrorString(){return this.fields.error_string}getETA(){return this.fields.eta}getFailedEver(){return this.fields.corrupt_ever}getFiles(){return this.fields.files||[]}getFile(e){return this.fields.files[e]}getFileCount(){return this.fields.file_count}getHashString(){return this.fields.hash_string}getHave(){return this.getHaveValid()+this.getHaveUnchecked()}getHaveUnchecked(){return this.fields.have_unchecked}getHaveValid(){return this.fields.have_valid}getId(){return this.fields.id}getLabels(){return this.fields.labels.toSorted()}getLastActivity(){return this.fields.activity_date}getLeftUntilDone(){return this.fields.left_until_done}getMagnetLink(){return this.fields.magnet_link}getMetadataPercentComplete(){return this.fields.metadata_percent_complete}getName(){return this.fields.name||"Unknown"}getPeers(){return this.fields.peers||[]}getPeersConnected(){return this.fields.peers_connected}getPeersGettingFromUs(){return this.fields.peers_getting_from_us}getPeersSendingToUs(){return this.fields.peers_sending_to_us}getPieceCount(){return this.fields.piece_count}getPieceSize(){return this.fields.piece_size}getPrimaryMimeType(){return this.fields.primary_mime_type||"application/octet-stream"}getPrivateFlag(){return this.fields.is_private}getQueuePosition(){return this.fields.queue_position}getRecheckProgress(){return this.fields.recheck_progress}getSeedRatioLimit(){return this.fields.seed_ratio_limit}getSeedRatioMode(){return this.fields.seed_ratio_mode}getSizeWhenDone(){return this.fields.size_when_done}getStartDate(){return this.fields.start_date}getStatus(){return this.fields.status}getTotalSize(){return this.fields.total_size}getTrackers(){return this.fields.trackers||[]}getUploadSpeed(){return this.fields.rate_upload}getUploadRatio(){return this.fields.upload_ratio}getUploadedEver(){return this.fields.uploaded_ever}getWebseedsSendingToUs(){return this.fields.webseeds_sending_to_us}isFinished(){return this.fields.is_finished}hasExtraInfo(){return"hash_string"in this.fields}isSeeding(){return this.getStatus()===n._StatusSeed}isStopped(){return this.getStatus()===n._StatusStopped}isChecking(){return this.getStatus()===n._StatusCheck}isDownloading(){return this.getStatus()===n._StatusDownload}isQueued(){return this.getStatus()===n._StatusDownloadWait||this.getStatus()===n._StatusSeedWait}isDone(){return this.getLeftUntilDone()<1}needsMetaData(){return this.getMetadataPercentComplete()<1}getActivity(){return this.getDownloadSpeed()+this.getUploadSpeed()}getPercentDoneStr(){return x.percentString(100*this.getPercentDone(),1)}getPercentDone(){return this.fields.percent_done}getStateString(){switch(this.getStatus()){case n._StatusStopped:return this.isFinished()?"Seeding complete":"Paused";case n._StatusCheckWait:return"Queued for verification";case n._StatusCheck:return"Verifying local data";case n._StatusDownloadWait:return"Queued for download";case n._StatusDownload:return"Downloading";case n._StatusSeedWait:return"Queued for seeding";case n._StatusSeed:return"Seeding";case null:return"Unknown";default:return"Error"}}seedRatioLimit(e){switch(this.getSeedRatioMode()){case n._RatioUseGlobal:return e.seedRatioLimit();case n._RatioUseLocal:return this.getSeedRatioLimit();default:return-1}}getErrorMessage(){let e=this.getErrorString();switch(this.getError()){case n._ErrTrackerWarning:return`Tracker returned a warning: ${e}`;case n._ErrTrackerError:return`Tracker returned an error: ${e}`;case n._ErrLocalError:return`Error: ${e}`;default:return null}}getCollatedName(){let e=this.fields;return!e.collatedName&&e.name&&(e.collatedName=e.name.toLowerCase()),e.collatedName||""}getCollatedTrackers(){let e=this.fields;return!e.collatedTrackers&&e.trackers&&(e.collatedTrackers=n.collateTrackers(e.trackers)),e.collatedTrackers||""}testState(e){let t=this.getStatus();switch(e){case p.FilterError:return this.getError();case p.FilterPrivate:return this.getPrivateFlag();case p.FilterPublic:return!this.getPrivateFlag();case p.FilterActive:return this.getPeersGettingFromUs()>0||this.getPeersSendingToUs()>0||this.getWebseedsSendingToUs()>0||this.isChecking();case p.FilterSeeding:return t===n._StatusSeed||t===n._StatusSeedWait;case p.FilterDownloading:return t===n._StatusDownload||t===n._StatusDownloadWait;case p.FilterPaused:return this.isStopped();case p.FilterFinished:return this.isFinished();default:return!0}}test(e,t,o,r){let s=this.testState(e);if(s&&o&&(s=this.getCollatedName().includes(o.toLowerCase())),s){let i=this.getLabels();r.length>0&&(s=r.some(a=>i.includes(a)))}return s&&t&&t.length>0&&(s=this.getCollatedTrackers().includes(t)),s}static compareById(e,t){return e.getId()-t.getId()}static compareByName(e,t){return e.getCollatedName().localeCompare(t.getCollatedName())||n.compareById(e,t)}static compareByQueue(e,t){return e.getQueuePosition()-t.getQueuePosition()}static compareByAge(e,t){let o=e.getDateAdded();return t.getDateAdded()-o||n.compareByQueue(e,t)}static compareByState(e,t){let o=e.getStatus();return t.getStatus()-o||n.compareByQueue(e,t)}static compareByActivity(e,t){let o=e.getActivity();return t.getActivity()-o||n.compareByState(e,t)}static compareByRatio(e,t){let o=e.getUploadRatio(),r=t.getUploadRatio();return or?-1:n.compareByState(e,t)}static compareByProgress(e,t){let o=e.getPercentDone(),r=t.getPercentDone();return o-r||n.compareByRatio(e,t)}static compareBySize(e,t){let o=e.getTotalSize(),r=t.getTotalSize();return o-r||n.compareByName(e,t)}static compareTorrents(e,t,o,r){let s=0;switch(o){case p.SortByActivity:s=n.compareByActivity(e,t);break;case p.SortByAge:s=n.compareByAge(e,t);break;case p.SortByQueue:s=n.compareByQueue(e,t);break;case p.SortByProgress:s=n.compareByProgress(e,t);break;case p.SortBySize:s=n.compareBySize(e,t);break;case p.SortByState:s=n.compareByState(e,t);break;case p.SortByRatio:s=n.compareByRatio(e,t);break;case p.SortByName:s=n.compareByName(e,t);break;default:console.log(`Unrecognized sort mode: ${o}`),s=n.compareByName(e,t);break}return r===p.SortDescending&&(s=-s),s}static sortTorrents(e,t,o){switch(t){case p.SortByActivity:e.sort(this.compareByActivity);break;case p.SortByAge:e.sort(this.compareByAge);break;case p.SortByName:e.sort(this.compareByName);break;case p.SortByProgress:e.sort(this.compareByProgress);break;case p.SortByQueue:e.sort(this.compareByQueue);break;case p.SortByRatio:e.sort(this.compareByRatio);break;case p.SortBySize:e.sort(this.compareBySize);break;case p.SortByState:e.sort(this.compareByState);break;default:console.log(`Unrecognized sort mode: ${t}`),e.sort(this.compareByName);break}return o===p.SortDescending&&e.reverse(),e}};A._StatusStopped=0;A._StatusCheckWait=1;A._StatusCheck=2;A._StatusDownloadWait=3;A._StatusDownload=4;A._StatusSeedWait=5;A._StatusSeed=6;A._RatioUseGlobal=0;A._RatioUseLocal=1;A._RatioUnlimited=2;A._ErrNone=0;A._ErrTrackerWarning=1;A._ErrTrackerError=2;A._ErrLocalError=3;A._TrackerInactive=0;A._TrackerWaiting=1;A._TrackerQueued=2;A._TrackerActive=3;A.Fields={};A.Fields.Metadata=["added_date","file_count","name","primary_mime_type","total_size"];A.Fields.Stats=["error","error_string","eta","is_finished","is_stalled","labels","left_until_done","metadata_percent_complete","peers_connected","peers_getting_from_us","peers_sending_to_us","percent_done","queue_position","rate_download","rate_upload","recheck_progress","seed_ratio_mode","seed_ratio_limit","size_when_done","status","trackers","download_dir","uploaded_ever","upload_ratio","webseeds_sending_to_us"];A.Fields.InfoExtra=["comment","creator","date_created","files","hash_string","is_private","magnet_link","piece_count","piece_size"];A.Fields.StatsExtra=["activity_date","corrupt_ever","desired_available","downloaded_ever","file_stats","have_unchecked","have_valid","peers","start_date","tracker_stats"];var Ge=["encryption","speed-up","speed-down","percent-done","status","peer-address","peer-app-name"],D=class n extends EventTarget{constructor(e){super(),this.closed=!1,this.controller=e,this.elements=this._create(),this.current_page=this.elements.info.root,this.interval=setInterval(this._refreshTorrents.bind(this),3e3),this.name="inspector",this.selection_listener=t=>this._setTorrents(t.selected),this.torrent_listener=()=>this._updateCurrentPage(),this.torrents=[],this.file_torrent=null,this.file_torrent_n=null,this.file_rows=null,this.elements.dismiss.addEventListener("click",()=>this.close()),Object.seal(this),e.addEventListener("torrent-selection-changed",this.selection_listener),this._setTorrents(this.controller.getSelectedTorrents()),document.querySelector("#mainwin-workarea").append(this.elements.root)}close(){if(!this.closed){clearInterval(this.interval),this._setTorrents([]),this.elements.root.remove(),this.controller.removeEventListener("torrent-selection-changed",this.selection_listener),this.dispatchEvent(new Event("close"));for(let e of Object.keys(this))this[e]=null;this.closed=!0}}static _createInfoPage(){let e=document.createElement("div");e.classList.add("inspector-info-page");let t={root:e},o=i=>{let a=document.createElement("div");a.textContent=i,a.classList.add("section-label"),e.append(a)},r=i=>{let a=document.createElement("label");b(a,i),e.append(a);let c=document.createElement("span");return e.append(c),c};o("Activity");let s=[["have","Have:"],["availability","Availability:"],["uploaded","Uploaded:"],["downloaded","Downloaded:"],["state","State:"],["running_time","Running time:"],["remaining_time","Remaining:"],["last_activity","Last activity:"],["error","Error:"]];for(let[i,a]of s)t[i]=r(a);o("Details"),s=[["name","Name:"],["size","Size:"],["location","Location:"],["hash","Hash:"],["privacy","Privacy:"],["origin","Origin:"],["date_added","Date added:"],["magnet_link","Magnet:"],["comment","Comment:"],["labels","Labels:"]];for(let[i,a]of s)t[i]=r(a);return t}static _createListPage(e,t){let o=document.createElement("div"),r=document.createElement(e);return r.id=t,o.append(r),{list:r,root:o}}static _createTiersPage(){return n._createListPage("div","inspector-tiers-list")}static _createFilesPage(){return n._createListPage("ul","inspector-file-list")}static _createPeersPage(){let e=document.createElement("table");e.classList.add("peer-list");let t=document.createElement("thead"),o=document.createElement("tr"),r=["","Up","Down","Done","Status","Address","Client"];for(let[i,a]of r.entries()){let c=document.createElement("th"),l=Ge[i];l==="encryption"&&(c.dataset.encrypted=!0),c.classList.add(l),b(c,a),o.append(c)}let s=document.createElement("tbody");return t.append(o),e.append(t),e.append(s),{root:e,tbody:s}}_create(){let e={files:n._createFilesPage(),info:n._createInfoPage(),peers:n._createPeersPage(),tiers:n._createTiersPage()},t=r=>{this.current_page=r,this._updateCurrentPage()};return{...M("inspector",[["inspector-tab-info",e.info.root,"Info"],["inspector-tab-peers",e.peers.root,"Peers"],["inspector-tab-tiers",e.tiers.root,"Tiers"],["inspector-tab-files",e.files.root,"Files"]],t.bind(this)),...e}}_setTorrents(e){let t="dataChanged",o=this.torrent_listener;for(let r of this.torrents)r.removeEventListener(t,o);this.torrents=[...e];for(let r of this.torrents)r.addEventListener(t,o);this._refreshTorrents(),this._updateCurrentPage()}static _needsExtraInfo(e){return e.some(t=>!t.hasExtraInfo())}_refreshTorrents(){let{controller:e,torrents:t}=this,o=t.map(r=>r.getId());if(o&&o.length>0){let r=["id",...A.Fields.StatsExtra];n._needsExtraInfo(t)&&r.push(...A.Fields.InfoExtra),e.updateTorrents(o,r)}}_updateCurrentPage(){let{current_page:e,elements:t}=this;switch(e){case t.files.root:this._updateFiles();break;case t.info.root:this._updateInfo();break;case t.peers.root:this._updatePeers();break;case t.tiers.root:this._updateTiers();break;default:console.warn("unexpected page"),console.log(e)}}_updateInfo(){let e="None",t="Mixed",o="Unknown",r=x,s=Date.now(),{elements:i,torrents:a}=this,c=a.reduce((d,g)=>d+g.getSizeWhenDone(),0),l=null;if(a.length===0)l=e;else if(a.every(d=>d.isFinished()))l="Finished";else if(a.every(d=>d.isStopped()))l="Paused";else{let d=m=>m.getStateString(),g=d(a[0]);l=a.every(m=>d(m)===g)?g:t}b(i.info.state,l);let u=l;if(a.length===0)l=e;else{let d=a.reduce((G,f)=>G+f.getHaveValid(),0),g=a.reduce((G,f)=>G+f.getHaveUnchecked(),0),m=a.reduce((G,f)=>G+f.getLeftUntilDone(),0),I=100*(c?(c-m)/c:1);l=r.percentString(I,1),g?l=`${r.size(d)} of ${r.size(c)} (${l}%), ${r.size(g)} Unverified`:m?l=`${r.size(d)} of ${r.size(c)} (${l}%)`:l=`${r.size(d)} (100%)`}if(b(i.info.have,r.stringSanitizer(l)),a.length===0)l=e;else if(c===0)l=e;else{let d=a.reduce((g,m)=>m.getHave()+m.getDesiredAvailable(),0);l=`${r.percentString(100*d/c,1)}%`}if(b(i.info.availability,r.stringSanitizer(l)),a.length===0)l=e;else{let d=a.reduce((m,I)=>m+I.getDownloadedEver(),0),g=a.reduce((m,I)=>m+I.getFailedEver(),0);l=g?`${r.size(d)} (+${r.size(g)} discarded after failed checksum)`:r.size(d)}if(b(i.info.downloaded,r.stringSanitizer(l)),a.length===0)l=e;else{let d=a.reduce((m,I)=>m+I.getUploadedEver(),0),g=a.reduce((m,I)=>m+I.getSizeWhenDone(),0)||a.reduce((m,I)=>m+I.getHaveValid(),0);l=`${r.size(d)} (Ratio: ${r.ratioString(S.ratio(d,g))})`}if(b(i.info.uploaded,l),a.length===0)l=e;else if(a.every(d=>d.isStopped()))l=u;else{let d=m=>m.getStartDate(),g=d(a[0]);l=a.every(m=>d(m)===g)?r.timeInterval(s/1e3-g):t}if(b(i.info.running_time,l),a.length===0)l=e;else{let d=m=>m.getETA(),g=d(a[0]);a.every(m=>d(m)===g)?g<0?l=o:l=r.timeInterval(g):l=t}if(b(i.info.remaining_time,l),a.length===0)l=e;else{let d=a.reduce((m,I)=>Math.max(m,I.getLastActivity()),-1),g=Math.floor(s/1e3);if(0m.getErrorString(),g=d(a[0]);l=a.every(m=>d(m)===g)?g:t}if(b(i.info.error,l||e),a.length===1?l=a[0].getName():l=a.length>0?t:e,b(i.info.name,l),a.length===0)l=e;else{let d=a.reduce((g,m)=>g+m.getTotalSize(),0);if(d){let g=f=>f.getPieceSize(),m=a.reduce((f,C)=>f+C.getPieceCount(),0),I=r.number(m),G=g(a[0]);l=a.every(f=>g(f)===G)?`${r.size(d)} (${I} pieces @ ${r.mem(G)})`:`${r.size(d)} (${I} pieces)`}else l="None"}if(b(i.info.size,r.stringSanitizer(l)),a.length===0)l=e;else{let d=m=>m.getHashString(),g=d(a[0]);l=a.every(m=>d(m)===g)?g:t}if(b(i.info.hash,l),a.length===0)l=e;else{let d=m=>m.getPrivateFlag(),g=d(a[0]);a.every(m=>d(m)===g)?g?l="Private to this tracker -- DHT and PEX disabled":l="Public torrent":l=t}if(b(i.info.privacy,l),a.length===0)l=e;else{let d=m=>m.getComment(),g=d(a[0]);l=a.every(m=>d(m)===g)?g:t}if(l=l||e,l.startsWith("https://")||l.startsWith("http://")?(l=encodeURI(l),i.info.comment.innerHTML=`${l}`):b(i.info.comment,l),l=a.length===0?e:a[0].getLabels().join(", "),b(i.info.labels,l),a.length===0)l=e;else{let d=h=>h.getCreator(),g=d(a[0]),m=!a.every(h=>d(h)===g);d=h=>h.getDateCreated();let I=d(a[0]),G=!a.every(h=>d(h)===I),f=!g||g.length===0,C=!I;m||G?l=t:f&&C?l=o:C&&!f?l=`Created by ${g}`:f&&!C?l=`Created on ${new Date(I*1e3).toDateString()}`:l=`Created by ${g} on ${new Date(I*1e3).toDateString()}`}if(b(i.info.origin,l),a.length===0)l=e;else{let d=m=>m.getDownloadDir(),g=d(a[0]);l=a.every(m=>d(m)===g)?g:t}if(b(i.info.location,l),a.length===0)l=e;else{let d=m=>m.getDateAdded(),g=d(a[0]);l=a.every(m=>d(m)===g)?new Date(g*1e3).toLocaleString(navigator.language,{day:"2-digit",hour:"2-digit",hour12:!1,minute:"2-digit",month:"short",second:"2-digit",timeZoneName:"short",weekday:"short",year:"numeric"}):t}if(b(i.info.date_added,l),a.length===0)b(i.info.magnet_link,e);else if(a.length>1)b(i.info.magnet_link,t);else{let d=a[0].getMagnetLink();i.info.magnet_link.innerHTML=``}}static _peerStatusTitle(e){let t=Object.seal({"?":"We unchoked this peer, but they're not interested",D:"Downloading from this peer",E:"Encrypted Connection",H:"Peer was discovered through Distributed Hash Table (DHT)",I:"Peer is an incoming connection",K:"Peer has unchoked us, but we're not interested",O:"Optimistic unchoke",T:"Peer is connected via uTP",U:"Uploading to peer",X:"Peer was discovered through Peer Exchange (PEX)",d:"We would download from this peer if they'd let us",u:"We would upload to this peer if they'd ask"});return[...e].filter(o=>t[o]).map(o=>`${o}: ${t[o]}`).join(` +`)}_updatePeers(){let e=x,{elements:t,torrents:o}=this,{tbody:r}=t.peers,s=[(a,c)=>{c.dataset.encrypted=a.is_encrypted},(a,c)=>b(c,a.rate_to_peer?e.speedBps(a.rate_to_peer):""),(a,c)=>b(c,a.rate_to_client?e.speedBps(a.rate_to_client):""),(a,c)=>b(c,`${Math.floor(a.progress*100)}%`),(a,c)=>{b(c,a.flag_str),c.setAttribute("title",n._peerStatusTitle(a.flag_str))},(a,c)=>{b(c,a.address),c.setAttribute("title",a.address)},(a,c)=>{b(c,a.client_name),c.setAttribute("title",a.client_name)}],i=[];for(let a of o){let c=document.createElement("tr");c.classList.add("torrent-row");let l=document.createElement("td");l.setAttribute("colspan",s.length),b(l,a.getName()),c.append(l),i.push(c);for(let u of a.getPeers()){let d=document.createElement("tr");d.classList.add("peer-row");for(let[g,m]of s.entries()){let I=document.createElement("td");I.classList.add(Ge[g]),m(u,I),d.append(I)}i.push(d)}for(;r.firstChild;)r.firstChild.remove();r.append(...i)}}static getAnnounceState(e){switch(e.announce_state){case A._TrackerActive:return"Announce in progress";case A._TrackerWaiting:{let t=Math.max(0,e.next_announce_time-Date.now()/1e3);return`Next announce in ${x.timeInterval(t)}`}case A._TrackerQueued:return"Announce is queued";case A._TrackerInactive:return e.is_backup?"Tracker will be used as a backup":"Announce not scheduled";default:return`unknown announce state: ${e.announce_state}`}}static lastAnnounceStatus(e){let t="Last Announce",o=["N/A"];if(e.has_announced){let r=x.timestamp(e.last_announce_time);e.last_announce_succeeded?o=[r," (got ",x.countString("peer","peers",e.last_announce_peer_count),")"]:(t="Announce error",o=[e.last_announce_result?`${e.last_announce_result} - `:"",r])}return{label:t,value:o.join("")}}static lastScrapeStatus(e){let t="Last Scrape",o="N/A";if(e.has_scraped){let r=x.timestamp(e.last_scrape_time);e.last_scrape_succeeded?o=r:(t="Scrape error",o=(e.last_scrape_result?`${e.last_scrape_result} - `:"")+r)}return{label:t,value:o}}static _getOrigin(e){try{let t="udp://";if(e.announce.startsWith(t)){let r="http://",s=e.announce.replace(t,r);return new URL(s).origin.replace(r,t)}return new URL(e.announce).origin}catch{return[e.sitename||e.host||e.announce]}}_updateTiers(){let{list:t}=this.elements.tiers,{torrents:o}=this,r=[];for(let s of o){if(o.length>1){let i=document.createElement("div");i.classList.add("tier-list-torrent"),b(i,s.getName()),r.push(i)}for(let i of s.getTrackers()){let a=n.getAnnounceState(i),c=n.lastAnnounceStatus(i),l=n.lastScrapeStatus(i),u=document.createElement("div");u.classList.add("tier-list-row");let d=document.createElement("div"),g=n._getOrigin(i);d.classList.add("tier-list-tracker"),b(d,`${g} - tier ${i.tier+1}`),d.setAttribute("title",i.announce),u.append(d),d=document.createElement("div"),d.classList.add("tier-announce"),b(d,`${c.label}: ${c.value}`),u.append(d),d=document.createElement("div"),d.classList.add("tier-seeders"),b(d,`Seeders: ${i.seeder_count>-1?i.seeder_count:"N/A"}`),u.append(d),d=document.createElement("div"),d.classList.add("tier-state"),b(d,a),u.append(d),d=document.createElement("div"),d.classList.add("tier-leechers"),b(d,`Leechers: ${i.leecher_count>-1?i.leecher_count:"N/A"}`),u.append(d),d=document.createElement("div"),d.classList.add("tier-scrape"),b(d,`${l.label}: ${l.value}`),u.append(d),d=document.createElement("div"),d.classList.add("tier-downloads"),b(d,`Downloads: ${i.download_count>-1?i.download_count:"N/A"}`),u.append(d),r.push(u)}}for(;t.firstChild;)t.firstChild.remove();t.append(...r)}_changeFileCommand(e,t){let{controller:o,file_torrent:r}=this,s=r.getId();o.changeFileCommand(s,e,t)}_onFileWantedToggled(e){let{indices:t,wanted:o}=e;this._changeFileCommand(t,o?"files_wanted":"files_unwanted")}_onFilePriorityToggled(e){let{indices:t,priority:o}=e,r=null;switch(o.toString()){case"-1":r="priority_low";break;case"1":r="priority_high";break;default:r="priority_normal"}this._changeFileCommand(t,r)}_clearFileList(){let{list:e}=this.elements.files;for(;e.firstChild;)e.firstChild.remove();this.file_torrent=null,this.file_torrent_n=null,this.file_rows=null}static createFileTreeModel(e){let t=[],o={children:{},file_indices:[]};for(let[r,s]of e.getFiles().entries()){let{name:i}=s,a=i.split("/"),c=o;for(let[l,u]of a.entries()){let d=c.children[u];d||(c.children[u]=d={children:{},depth:l,file_indices:[],name:u,parent:c}),c=d}c.file_index=r,delete c.children,t.push(c)}for(let r of t){let{file_index:s}=r,i=r;do i.file_indices.push(s),i=i.parent;while(i)}return o}addNodeToView(e,t,o){let r=new oe(this.controller,e,o);r.addEventListener("wantedToggled",this._onFileWantedToggled.bind(this)),r.addEventListener("priorityToggled",this._onFilePriorityToggled.bind(this)),this.file_rows.push(r),t.append(r.getElement())}addSubtreeToView(e,t,o){if(o.parent&&this.addNodeToView(e,t,o),o.children)for(let r of Object.values(o.children))this.addSubtreeToView(e,t,r)}_updateFiles(){let{list:e}=this.elements.files,{file_rows:t,file_torrent:o,file_torrent_n:r,torrents:s}=this;if(s.length!==1){this._clearFileList();return}let[i]=s,a=i.getFiles().length;if(i!==o||a!==r){this._clearFileList(),this.file_torrent=i,this.file_torrent_n=a,this.file_rows=[];let c=document.createDocumentFragment(),l=n.createFileTreeModel(i);this.addSubtreeToView(i,c,l),e.append(c)}else for(let c of t)c.refresh()}};var re=class n extends EventTarget{constructor(e,t){super(),this.controller=e,this.remote=t,this.elements={},this.torrents=[],this.show()}show(){let e=this.controller.getSelectedTorrents();e.length!==0&&(this.torrents=e,this.elements=n._create(),this.elements.confirm.addEventListener("click",()=>this._onConfirm()),this.elements.dismiss.addEventListener("click",()=>this._onDismiss()),this.elements.entry.value=e[0].getDownloadDir(),document.body.append(this.elements.root),this.elements.entry.focus())}close(){this.elements.root.remove(),this.dispatchEvent(new Event("close")),delete this.controller,delete this.remote,delete this.elements,delete this.torrents}_onDismiss(){this.close()}_onConfirm(){let e=this.torrents.map(o=>o.getId()),t=this.elements.entry.value.trim();this.remote.moveTorrents(e,t),this.close()}static _create(){let e=X("move-dialog");e.root.setAttribute("aria-label","Move Torrent"),e.heading.textContent="Set Torrent Location",confirm.textContent="Apply";let t=document.createElement("label");t.setAttribute("for","torrent-path"),t.textContent="Location:",e.workarea.append(t);let o=document.createElement("input");return o.setAttribute("type","text"),o.id="torrent-path",e.entry=o,e.workarea.append(o),e}};var k=class n extends EventTarget{constructor(e){super(),this.elements=n._create(e),this.elements.dismiss.addEventListener("click",()=>this._onDismiss()),this.options=e,document.body.append(this.elements.root),this.elements.dismiss.focus()}close(){if(!this.closed){this.elements.root.remove(),this.dispatchEvent(new Event("close"));for(let e of Object.keys(this))delete this[e];this.closed=!0}}_onDismiss(){this.close()}static _create(e){let{heading:t,message:o}=e,r=X("confirm-dialog");return r.confirm.remove(),delete r.confirm,r.heading.textContent=t,r.workarea.textContent=o,r}};var B={_DaemonVersion:"version",_DownSpeedLimit:"speed_limit_down",_DownSpeedLimited:"speed_limit_down_enabled",_JsonRpcVersion:"2.0",_QueueMoveBottom:"queue_move_bottom",_QueueMoveDown:"queue_move_down",_QueueMoveTop:"queue_move_top",_QueueMoveUp:"queue_move_up",_Root:"../rpc",_TurtleDownSpeedLimit:"alt_speed_down",_TurtleState:"alt_speed_enabled",_TurtleUpSpeedLimit:"alt_speed_up",_UpSpeedLimit:"speed_limit_up",_UpSpeedLimited:"speed_limit_up_enabled"},E=class n{_connection_alert=null;_session_id="";constructor(e){this._controller=e}sendRequest(e,t,o){let r=new Headers;r.append("cache-control","no-cache"),r.append("content-type","application/json"),r.append("pragma","no-cache"),this._session_id&&r.append(n._SessionHeader,this._session_id);let s=null;fetch(B._Root,{body:JSON.stringify(e),headers:r,method:"POST"}).then(i=>{switch(s=i,i.status){case 409:{let a=new Error(n._SessionHeader);throw a.header=i.headers.get(n._SessionHeader),a}case 204:return null;default:return i.json()}}).then(i=>{t&&t.call(o,i,s),this._connection_alert&&(this._connection_alert.close(),this._connection_alert=null)}).catch(i=>{if(i.message===n._SessionHeader){this._session_id=i.header,this.sendRequest(e,t,o);return}console.trace(i),this._controller.togglePeriodicSessionRefresh(!1),this._connection_alert=new k({heading:"Connection failed",message:"Could not connect to the server. You may need to reload the page to reconnect."}),this._controller.setCurrentPopup(this._connection_alert)})}loadDaemonPrefs(e,t){let o={id:"webui",jsonrpc:B._JsonRpcVersion,method:"session_get"};this.sendRequest(o,e,t)}checkPort(e,t,o){let r={id:"webui",jsonrpc:B._JsonRpcVersion,method:"port_test",params:{ip_protocol:e}};this.sendRequest(r,t,o)}renameTorrent(e,t,o,r,s){let i={id:"webui",jsonrpc:B._JsonRpcVersion,method:"torrent_rename_path",params:{ids:e,name:o,path:t}};this.sendRequest(i,r,s)}setLabels(e,t,o){let r={ids:e,labels:t};this.sendRequest({id:"webui",jsonrpc:B._JsonRpcVersion,method:"torrent_set",params:r},o)}loadDaemonStats(e,t){let o={id:"webui",jsonrpc:B._JsonRpcVersion,method:"session_stats"};this.sendRequest(o,e,t)}updateTorrents(e,t,o,r){let s={id:"webui",jsonrpc:B._JsonRpcVersion,method:"torrent_get",params:{fields:t,format:"table"}};e&&(s.params.ids=e),this.sendRequest(s,i=>{let{torrents:a,removed:c}=i.result;o.call(r,a,c)})}getFreeSpace(e,t,o){let r={id:"webui",jsonrpc:B._JsonRpcVersion,method:"free_space",params:{path:e}};this.sendRequest(r,s=>{let{path:i,size_bytes:a}=s.result;t.call(o,i,a)})}changeFileCommand(e,t,o){let r={ids:[e]};r[o]=t,this.sendRequest({jsonrpc:B._JsonRpcVersion,method:"torrent_set",params:r},()=>{this._controller.refreshTorrents([e])})}sendTorrentSetRequests(e,t,o,r,s){o||={},o.ids=t;let i={id:"webui",jsonrpc:B._JsonRpcVersion,method:e,params:o};this.sendRequest(i,r,s)}sendTorrentActionRequests(e,t,o,r){this.sendTorrentSetRequests(e,t,null,o,r)}startTorrents(e,t,o,r){let s=t?"torrent_start_now":"torrent_start";this.sendTorrentActionRequests(s,e,o,r)}stopTorrents(e,t,o){this.sendTorrentActionRequests("torrent_stop",e,t,o)}moveTorrents(e,t,o,r){this.sendTorrentSetRequests("torrent_set_location",e,{location:t,move:!0},o,r)}removeTorrents(e,t){let o={jsonrpc:B._JsonRpcVersion,method:"torrent_remove",params:{delete_local_data:t,ids:[]}};if(e)for(let r=0,s=e.length;r{this._controller.refreshTorrents()})}verifyTorrents(e,t,o){this.sendTorrentActionRequests("torrent_verify",e,t,o)}reannounceTorrents(e,t,o){this.sendTorrentActionRequests("torrent_reannounce",e,t,o)}addTorrentByUrl(e,t){/^[\da-f]{40}$/i.test(e)&&(e=`magnet:?xt=urn:btih:${e}`);let o={jsonrpc:B._JsonRpcVersion,method:"torrent_add",params:{filename:e,paused:t.paused}};this.sendRequest(o,()=>{this._controller.refreshTorrents()})}savePrefs(e){let t={jsonrpc:B._JsonRpcVersion,method:"session_set",params:e};this.sendRequest(t,()=>{this._controller.loadDaemonPrefs()})}updateBlocklist(){let e={jsonrpc:B._JsonRpcVersion,method:"blocklist_update"};this.sendRequest(e,()=>{this._controller.loadDaemonPrefs()})}moveTorrentsToTop(e,t,o){this.sendTorrentActionRequests(B._QueueMoveTop,e,t,o)}moveTorrentsToBottom(e,t,o){this.sendTorrentActionRequests(B._QueueMoveBottom,e,t,o)}moveTorrentsUp(e,t,o){this.sendTorrentActionRequests(B._QueueMoveUp,e,t,o)}moveTorrentsDown(e,t,o){this.sendTorrentActionRequests(B._QueueMoveDown,e,t,o)}};E._SessionHeader="X-Transmission-Session-Id";var Se=/iPad|iPhone|iPod/.test(navigator.userAgent)&&!globalThis.MSStream,De=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),Ee=!(Se&&De),V=class extends EventTarget{constructor(e,t,o="",r=null){super(),this.controller=e,this.remote=t,this.elements=this._create(o),this.elements.dismiss.addEventListener("click",()=>this._onDismiss()),this.elements.confirm.addEventListener("click",()=>this._onConfirm()),document.body.append(this.elements.root),r&&(this.elements.file_input.files=r),this._updateFreeSpaceInAddDialog(),this.elements.url_input.focus()}close(){if(!this.closed){clearInterval(this.interval),this.elements.root.remove(),this.dispatchEvent(new Event("close"));for(let e of Object.keys(this))delete this[e];this.closed=!0}}_onDismiss(){this.close()}_updateFreeSpaceInAddDialog(){let e=this.elements.folder_input.value;this.remote.getFreeSpace(e,(t,o)=>{this.closed||(this.elements.freespace.textContent=o>0?`${x.size(o)} Free`:"")})}_onConfirm(){let{controller:e,elements:t,remote:o}=this,{file_input:r,folder_input:s,start_input:i,url_input:a}=t,c=!i.checked,l=s.value.trim();for(let d of r.files){let g=new FileReader;g.addEventListener("load",m=>{let I=m.target.result,G="base64,",f=I.indexOf(G);if(f===-1)return;let C={id:"webui",jsonrpc:B._JsonRpcVersion,method:"torrent_add",params:{download_dir:l,metainfo:I.slice(Math.max(0,f+G.length)),paused:c}};o.sendRequest(C,h=>{if("error"in h){let y=h.error.data?.errorString??h.error.message;alert(`Error adding "${d.name}": ${y}`),e.setCurrentPopup(new k({heading:`Error adding "${d.name}"`,message:y}))}})}),g.readAsDataURL(d)}let u=a.value.trim();if(u.length>0){/^[\da-f]{40}$/i.test(u)&&(u=`magnet:?xt=urn:btih:${u}`);let d={id:"webui",jsonrpc:B._JsonRpcVersion,method:"torrent_add",params:{download_dir:l,filename:u,paused:c}};o.sendRequest(d,g=>{"error"in g&&e.setCurrentPopup(new k({heading:`Error adding "${u}"`,message:g.error.data?.errorString??g.error.message}))})}this._onDismiss()}_create(e){let t=X(),{confirm:o,root:r,heading:s,workarea:i}=t;r.classList.add("open-torrent"),s.textContent="Add Torrents",o.textContent="Add";let a=v(),c=document.createElement("label");c.setAttribute("for",a),c.textContent="Please select torrent files to add:",i.append(c);let l=document.createElement("input");l.type="file",l.name="torrent-files[]",l.id=a,l.multiple=!0,Ee&&(l.accept=".torrent,application/x-bittorrent"),i.append(l),t.file_input=l,a=v(),c=document.createElement("label"),c.setAttribute("for",a),c.textContent="Or enter a URL:",i.append(c),l=document.createElement("input"),l.type="url",l.id=a,l.value=e,i.append(l),t.url_input=l,a=v(),c=document.createElement("label"),c.id="add-dialog-folder-label",c.for=a,c.textContent="Destination folder: ",i.append(c);let u=document.createElement("span");u.id="free-space-text",c.append(u),i.append(c),t.freespace=u,l=document.createElement("input"),l.type="text",l.id="add-dialog-folder-input",l.addEventListener("change",()=>this._updateFreeSpaceInAddDialog()),l.value=this.controller.session_properties.download_dir,i.append(l),t.folder_input=l;let d=document.createElement("div");i.append(d);let g=document.createElement("input");return g.type="checkbox",g.id="auto-start-check",g.checked=this.controller.shouldAddedTorrentsStart(),d.append(g),t.start_input=g,c=document.createElement("label"),c.id="auto-start-label",c.setAttribute("for",g.id),c.textContent="Start when added",d.append(c),t}};function se(n,e){let t=document.createElement("fieldset");t.classList.add("section",n);let o=document.createElement("legend");return o.classList.add("title"),o.textContent=e,t.append(o),t}function xe(n,e,t,o){let r=document.createElement("button");return r.textContent=e,r.addEventListener("click",o),n.append(r),r.dataset.action=t,r}var J=class extends EventTarget{constructor(e,t,o,r){super(),this.action_listener=this._onActionChange.bind(this),this.action_manager=r,this.action_manager.addEventListener("change",this.action_listener),this.prefs_listener=this._onPrefsChange.bind(this),this.prefs=t,this.prefs.addEventListener("change",this.prefs_listener),this.closed=!1,this.remote=o,this.name="overflow-menu",this.session_listener=this._onSessionChange.bind(this),this.session_manager=e,this.session_manager.addEventListener("session-change",this.session_listener);let{session_properties:s}=e;Object.assign(this,this._create(s)),this.outside=new _(this.root),this.outside.addEventListener("click",()=>this.close()),Object.seal(this),this.show()}show(){document.body.append(this.root)}close(){if(!this.closed){this.outside.stop(),this.session_manager.removeEventListener("session-change",this.session_listener),this.action_manager.removeEventListener("change",this.action_listener),this.prefs.removeEventListener("change",this.prefs_listener),this.root.remove(),this.dispatchEvent(new Event("close"));for(let e of Object.keys(this))this[e]=null;this.closed=!0}}_onSessionChange(e){let{alt_speed_check:t}=this.elements,{session_properties:o}=e;t.checked=o[B._TurtleState]}_onPrefsChange(e){switch(e.key){case p.SortDirection:case p.SortMode:this.root.querySelector(`[data-pref="${e.key}"]`).value=e.value;break;default:break}}_onActionChange(e){let t=this.actions[e.action];t&&this._updateElement(t)}_updateElement(e){if(e.dataset.action){let{action:t}=e.dataset,o=this.action_manager.keyshortcuts(t);o&&e.setAttribute("aria-keyshortcuts",o),w(e,this.action_manager.isEnabled(t))}}_onClick(e){let{action:t,pref:o}=e.target.dataset;if(t){this.action_manager.click(t);return}if(o){this.prefs[o]=e.target.value;return}console.log("unhandled"),console.log(e),console.trace()}_create(e){let t={},o={},r=this._onClick.bind(this),s=document.createElement("div");s.classList.add("overflow-menu","popup");let i=document.createElement("div"),a=(C,h)=>{let y=document.createElement("input");y.id=v(),y.type="checkbox";let U=document.createElement("label");U.htmlFor=y.id,U.textContent=C,i.append(y,U),h(y)},c=se("display","Display");s.append(c);let l=document.createElement("div");l.id="display-options",c.append(l),i.classList.add("table-row"),l.append(i);let u=document.createElement("label");u.id="display-sort-mode-label",u.textContent="Sort by",i.append(u);let d=document.createElement("select");d.id="display-sort-mode-select",d.dataset.pref=p.SortMode,i.append(d);let g=[[p.SortByActivity,"Activity"],[p.SortByAge,"Age"],[p.SortByName,"Name"],[p.SortByProgress,"Progress"],[p.SortByQueue,"Queue order"],[p.SortByRatio,"Ratio"],[p.SortBySize,"Size"],[p.SortByState,"State"]];for(let[C,h]of g){let y=document.createElement("option");y.value=C,y.textContent=h,d.append(y)}u.htmlFor=d.id,d.value=this.prefs.sort_mode,d.addEventListener("change",C=>{this.prefs.sort_mode=C.target.value}),i=document.createElement("div"),i.classList.add("table-row"),l.append(i);let m=C=>{C.dataset.pref=p.SortDirection,C.checked=this.prefs.sort_direction!==p.SortAscending,C.addEventListener("input",h=>{this.prefs.sort_direction=h.target.checked?p.SortDescending:p.SortAscending})};a("Reverse sort",m),i=document.createElement("div"),i.classList.add("table-row"),l.append(i),m=C=>{C.checked=this.prefs.display_mode===p.DisplayCompact,C.addEventListener("change",h=>{let{checked:y}=h.target;this.prefs.display_mode=y?p.DisplayCompact:p.DisplayFull})},a(this.action_manager.text("toggle-compact-rows"),m),i=document.createElement("div"),i.classList.add("table-row"),l.append(i),m=C=>{C.checked=this.prefs.contrast_mode===p.ContrastMore,C.addEventListener("change",h=>{let{checked:y}=h.target;this.prefs.contrast_mode=y?p.ContrastMore:p.ContrastLess})},a(this.action_manager.text("toggle-contrast"),m),i=document.createElement("div"),i.classList.add("table-row","display-fullscreen-row"),l.append(i),m=C=>{let h=()=>document.fullscreenElement!==null;C.checked=h(),document.addEventListener("fullscreenchange",()=>{C.checked=h()}),C.addEventListener("change",()=>{h()?document.exitFullscreen():document.body.requestFullscreen()})},a("Fullscreen",m),c=se("speed","Speed Limit"),s.append(c),l=document.createElement("div"),l.id="speed-options",c.append(l),i=document.createElement("div"),i.classList.add("speed-up"),l.append(i),u=document.createElement("label"),u.id="speed-up-label",u.textContent="Upload:",i.append(u);let I="Unlimited";d=document.createElement("select"),d.id="speed-up-select",i.append(d);let G=["50","100","250","500","1000","2500","5000","10000",I];for(let C of[...new Set(G).add(`${e[B._UpSpeedLimit]}`).values()].toSorted((h,y)=>h-y)){let h=document.createElement("option");h.value=C,h.textContent=C===I?I:x.speed(C),d.append(h)}u.htmlFor=d.id,d.value=e[B._UpSpeedLimited]?`${e[B._UpSpeedLimit]}`:I,d.addEventListener("change",C=>{let{value:h}=C.target;console.log(C),h===I?this.remote.savePrefs({[B._UpSpeedLimited]:!1}):this.remote.savePrefs({[B._UpSpeedLimited]:!0,[B._UpSpeedLimit]:Number.parseInt(h,10)})}),i=document.createElement("div"),i.classList.add("speed-down"),l.append(i),u=document.createElement("label"),u.id="speed-down-label",u.textContent="Download:",i.append(u),d=document.createElement("select"),d.id="speed-down-select",i.append(d);for(let C of[...new Set(G).add(`${e[B._DownSpeedLimit]}`).values()].toSorted((h,y)=>h-y)){let h=document.createElement("option");h.value=C,h.textContent=C===I?I:x.speed(C),d.append(h)}u.htmlFor=d.id,d.value=e[B._DownSpeedLimited]?`${e[B._DownSpeedLimit]}`:I,d.addEventListener("change",C=>{let{value:h}=C.target;console.log(C),h===I?this.remote.savePrefs({[B._DownSpeedLimited]:!1}):this.remote.savePrefs({[B._DownSpeedLimited]:!0,[B._DownSpeedLimit]:Number.parseInt(h,10)})}),i=document.createElement("div"),i.classList.add("alt-speed"),l.append(i),m=C=>{C.checked=e[B._TurtleState],o.alt_speed_check=C,C.addEventListener("change",O=>{this.remote.savePrefs({[B._TurtleState]:O.target.checked})});let h=document.createElement("label");h.htmlFor=C.id,h.id="alt-speed-image";let y=document.createElement("label");y.htmlFor=C.id;let U=x.speed(e[B._TurtleUpSpeedLimit]),H=x.speed(e[B._TurtleDownSpeedLimit]);y.textContent=`(${U} up, ${H} down)`,i.append(h,y)},a("Use Temp limits",m),c=se("actions","Actions"),s.append(c);for(let C of["show-preferences-dialog","show-shortcuts-dialog","pause-all-torrents","start-all-torrents"]){let h=this.action_manager.text(C);t[C]=xe(c,h,C,r)}c=se("help","Help"),s.append(c),l=document.createElement("div"),c.append(l);for(let C of["show-statistics-dialog","show-about-dialog"]){let h=this.action_manager.text(C);t[C]=xe(l,h,C,r)}let f=document.createElement("a");return f.href="https://transmissionbt.com/donate.html",f.target="_blank",f.textContent="Donate",l.append(f),this._updateElement=this._updateElement.bind(this),{actions:t,elements:o,root:s}}};var ie=class n extends EventTarget{static _initTimeDropDown(e){for(let t=0;t<96;++t){let o=t/4,r=t%4*15,s=t*15,i=`${o}:${r||"00"}`;e.options[t]=new Option(i,s)}}static _initDayDropDown(e){let t=[["Everyday","127"],["Weekdays","62"],["Weekends","65"],["Sunday","1"],["Monday","2"],["Tuesday","4"],["Wednesday","8"],["Thursday","16"],["Friday","32"],["Saturday","64"]];for(let o=0;t[o];++o){let[r,s]=t[o];e.options[o]=new Option(r,s)}}_checkPort(){for(let[e,t]of Object.entries(this.elements.network.port_status_label))delete t.dataset.open,b(t,"Checking..."),this.remote.checkPort(e,o=>this._onPortChecked(e,o),this)}_onPortChecked(e,t){if(this.closed)return;let o=t.result??t.error?.data??{},r=this.elements.network.port_status_label[e],s=o.port_is_open??!1;r.dataset.open=s,"port_is_open"in o?b(r,s?"Open":"Closed"):b(r,"Error")}_setBlocklistButtonEnabled(e){let t=this.elements.peers.blocklist_update_button;w(t,e),t.value=e?"Update":"Updating..."}static _getValue(e){if(e.tagName==="TEXTAREA")return e.value;switch(e.type){case"checkbox":case"radio":return e.checked;case"number":case"select-one":case"text":case"url":{let t=e.value;return Number.parseInt(t,10).toString()===t?Number.parseInt(t,10):Number.parseFloat(t).toString()===t?Number.parseFloat(t):t}default:return null}}_onMaybePortChanged(e){(e==="peer_port"||e==="port_forwarding_enabled")&&this._checkPort()}_onControlChanged(e){let{key:t}=e.target.dataset;this.remote.savePrefs({[t]:n._getValue(e.target)}),this._onMaybePortChanged(t)}_onDialogClosed(){this.dispatchEvent(new Event("closed"))}_update(){this._setBlocklistButtonEnabled(!0);for(let[e,t]of Object.entries(this.session_manager.session_properties))for(let o of this.elements.root.querySelectorAll(`[data-key="${e}"]`)){if(e==="blocklist_size"){let r=x.number(t);o.innerHTML=`Blocklist has ${r} rules`,b(this.elements.peers.blocklist_update_button,"Update")}else switch(o.type){case"checkbox":case"radio":o.checked=t;break;case"text":case"textarea":case"url":case"email":case"number":case"search":o!==document.activeElement&&(o.value!=t&&this._onMaybePortChanged(e),o.value=t);break;case"select-one":o.value=t;break;default:console.log(o.type);break}o.dispatchEvent(new Event("session-change"))}}static _createCheckAndLabel(e,t){let o=document.createElement("div");o.id=e;let r=document.createElement("input");r.id=v(),r.type="checkbox",o.append(r);let s=document.createElement("label");return s.textContent=t,s.setAttribute("for",r.id),o.append(s),{check:r,label:s,root:o}}static _enableIfChecked(e,t){let o=()=>{e.tagName==="INPUT"?w(e,t.checked):e.classList.toggle("disabled",!t.checked)};t.addEventListener("session-change",o),o()}static _getProtocolHandlerRegistered(){return localStorage.getItem("protocol-handler-registered")==="true"}static _updateProtocolHandlerButton(e){e.removeAttribute("disabled"),e.removeAttribute("title"),n._getProtocolHandlerRegistered()?(e.textContent="Remove Browser Handler","unregisterProtocolHandler"in navigator||e.setAttribute("title","Your browser does not support removing protocol handlers. This button only allows you to re-register a handler.")):(e.textContent="Add Browser Handler",e.removeAttribute("title"),"registerProtocolHandler"in navigator||(e.setAttribute("disabled",!0),e.setAttribute("title","Your browser does not support protocol handlers")))}static _toggleProtocolHandler(e){let t=new URL(globalThis.location.href);t.search="addtorrent=%s",this._getProtocolHandlerRegistered()?(navigator.unregisterProtocolHandler?.("magnet",t.toString()),localStorage.removeItem("protocol-handler-registered"),n._updateProtocolHandlerButton(e)):(navigator.registerProtocolHandler("magnet",t.toString(),"Transmission Web"),localStorage.setItem("protocol-handler-registered","true"),n._updateProtocolHandlerButton(e))}static _createTorrentsPage(){let e=document.createElement("div");e.classList.add("prefs-torrents-page");let t=document.createElement("div");t.textContent="Downloading",t.classList.add("section-label"),e.append(t),t=document.createElement("label"),t.textContent="Download to:",e.append(t);let o=document.createElement("input");o.type="text",o.id=v(),o.dataset.key="download_dir",t.setAttribute("for",o.id),e.append(o);let r=o,s=n._createCheckAndLabel("incomplete-dir-div","Use temporary folder:");s.check.title="Separate folder to temporarily store downloads until they are complete.",s.check.dataset.key="incomplete_dir_enabled",s.label.title=s.check.title,e.append(s.root);let i=s.check;o=document.createElement("input"),o.type="text",o.dataset.key="incomplete_dir",e.append(o),n._enableIfChecked(o,s.check);let a=o;s=n._createCheckAndLabel("autostart-div","Start when added"),s.check.dataset.key="start_added_torrents",e.append(s.root);let c=s.check;s=n._createCheckAndLabel("suffix-div",`Append "part" to incomplete files' names`),s.check.dataset.key="rename_partial_files",e.append(s.root);let l=s.check;s=n._createCheckAndLabel("download-queue-div","Download queue size:"),s.check.dataset.key="download_queue_enabled",e.append(s.root);let u=s.check;o=document.createElement("input"),o.type="number",o.dataset.key="download_queue_size",e.append(o),n._enableIfChecked(o,s.check);let d=o;t=document.createElement("div"),t.textContent="Seeding",t.classList.add("section-label"),e.append(t),s=n._createCheckAndLabel("stop-ratio-div","Stop seeding at ratio:"),s.check.dataset.key="seed_ratio_limited",e.append(s.root);let g=s.check;o=document.createElement("input"),o.type="number",o.min="0.1",o.step="any",o.dataset.key="seed_ratio_limit",e.append(o),n._enableIfChecked(o,s.check);let m=o;s=n._createCheckAndLabel("stop-idle-div","Stop seeding if idle for N mins:"),s.check.dataset.key="idle_seeding_limit_enabled",e.append(s.root);let I=s.check;o=document.createElement("input"),o.type="number",o.min="0.1",o.step="any",o.dataset.key="idle_seeding_limit",e.append(o),n._enableIfChecked(o,s.check);let G=o;t=document.createElement("div"),t.textContent="Magnet Protocol Handler",t.classList.add("section-label"),e.append(t);let f=document.createElement("button");return f.classList.add("register-handler-button"),n._updateProtocolHandlerButton(f),e.append(f),{autostart_check:c,download_dir:r,download_queue_check:u,download_queue_input:d,incomplete_dir_check:i,incomplete_dir_input:a,register_handler_button:f,root:e,stop_idle_check:I,stop_idle_input:G,stop_ratio_check:g,stop_ratio_input:m,suffix_check:l}}static _createSpeedPage(){let e=document.createElement("div");e.classList.add("prefs-speed-page");let t=document.createElement("div");t.textContent="Speed Limits",t.classList.add("section-label"),e.append(t);let o=n._createCheckAndLabel("upload-speed-div","Upload (kB/s):");o.check.dataset.key="speed_limit_up_enabled",e.append(o.root);let r=o.check,s=document.createElement("input");s.type="number",s.dataset.key="speed_limit_up",e.append(s),n._enableIfChecked(s,o.check);let i=s;o=n._createCheckAndLabel("download-speed-div","Download (kB/s):"),o.check.dataset.key="speed_limit_down_enabled",e.append(o.root);let a=o.check;s=document.createElement("input"),s.type="number",s.dataset.key="speed_limit_down",e.append(s),n._enableIfChecked(s,o.check);let c=s;t=document.createElement("div"),t.textContent="Alternative Speed Limits",t.classList.add("section-label","alt-speed-section-label"),e.append(t),t=document.createElement("div"),t.textContent="Override normal speed limits manually or at scheduled times",t.classList.add("alt-speed-label"),e.append(t),t=document.createElement("label"),t.textContent="Upload (kB/s):",e.append(t),s=document.createElement("input"),s.type="number",s.dataset.key="alt_speed_up",s.id=v(),t.setAttribute("for",s.id),e.append(s);let l=s;t=document.createElement("label"),t.textContent="Download (kB/s):",e.append(t),s=document.createElement("input"),s.type="number",s.dataset.key="alt_speed_down",s.id=v(),t.setAttribute("for",s.id),e.append(s);let u=s;o=n._createCheckAndLabel("alt-times-div","Scheduled times"),o.check.dataset.key="alt_speed_time_enabled",e.append(o.root);let d=o.check;t=document.createElement("label"),t.textContent="From:",n._enableIfChecked(t,o.check),e.append(t);let g=document.createElement("select");g.id=v(),g.dataset.key="alt_speed_time_begin",n._initTimeDropDown(g),t.setAttribute("for",g.id),e.append(g),n._enableIfChecked(g,o.check);let m=g;t=document.createElement("label"),t.textContent="To:",n._enableIfChecked(t,o.check),e.append(t),g=document.createElement("select"),g.id=v(),g.dataset.key="alt_speed_time_end",n._initTimeDropDown(g),t.setAttribute("for",g.id),e.append(g),n._enableIfChecked(g,o.check);let I=g;return t=document.createElement("label"),t.textContent="On days:",n._enableIfChecked(t,o.check),e.append(t),g=document.createElement("select"),g.id=v(),g.dataset.key="alt_speed_time_day",n._initDayDropDown(g),t.setAttribute("for",g.id),e.append(g),n._enableIfChecked(g,o.check),{alt_days_select:g,alt_download_speed_input:u,alt_from_select:m,alt_times_check:d,alt_to_select:I,alt_upload_speed_input:l,download_speed_check:a,download_speed_input:c,root:e,upload_speed_check:r,upload_speed_input:i}}static _createPeersPage(){let e=document.createElement("div");e.classList.add("prefs-peers-page");let t=document.createElement("div");t.textContent="Connections",t.classList.add("section-label"),e.append(t),t=document.createElement("label"),t.textContent="Max peers per torrent:",e.append(t);let o=document.createElement("input");o.type="number",o.dataset.key="peer_limit_per_torrent",o.id=v(),t.setAttribute("for",o.id),e.append(o);let r=o;t=document.createElement("label"),t.textContent="Max peers overall:",e.append(t),o=document.createElement("input"),o.type="number",o.dataset.key="peer_limit_global",o.id=v(),t.setAttribute("for",o.id),e.append(o);let s=o;t=document.createElement("div"),t.textContent="Options",t.classList.add("section-label"),e.append(t),t=document.createElement("label"),t.textContent="Encryption mode:",e.append(t);let i=document.createElement("select");i.id=v(),i.dataset.key="encryption",i.options[0]=new Option("Prefer encryption","preferred"),i.options[1]=new Option("Allow encryption","tolerated"),i.options[2]=new Option("Require encryption","required"),e.append(i);let a=i,c=n._createCheckAndLabel("use-pex-div","Use PEX to find more peers");c.check.title="PEX is a tool for exchanging peer lists with the peers you're connected to.",c.check.dataset.key="pex_enabled",c.label.title=c.check.title,e.append(c.root);let l=c.check;c=n._createCheckAndLabel("use-dht-div","Use DHT to find more peers"),c.check.title="DHT is a tool for finding peers without a tracker.",c.check.dataset.key="dht_enabled",c.label.title=c.check.title,e.append(c.root);let u=c.check;c=n._createCheckAndLabel("use-lpd-div","Use LPD to find more peers"),c.check.title="LPD is a tool for finding peers on your local network.",c.check.dataset.key="lpd_enabled",c.label.title=c.check.title,e.append(c.root);let d=c.check;t=document.createElement("div"),t.textContent="Blocklist",t.classList.add("section-label"),e.append(t),c=n._createCheckAndLabel("blocklist-enabled-div","Enable blocklist:"),c.check.dataset.key="blocklist_enabled",e.append(c.root);let g=c.check;o=document.createElement("input"),o.type="url",o.value="http://www.example.com/blocklist",o.dataset.key="blocklist_url",e.append(o),n._enableIfChecked(o,c.check);let m=o;t=document.createElement("label"),t.textContent="Blocklist has {n} rules",t.dataset.key="blocklist_size",t.classList.add("blocklist-size-label"),n._enableIfChecked(t,c.check),e.append(t);let I=document.createElement("button");return I.classList.add("blocklist-update-button"),I.textContent="Update",e.append(I),n._enableIfChecked(I,c.check),{blocklist_enabled_check:g,blocklist_update_button:I,blocklist_url_input:m,dht_check:u,encryption_select:a,lpd_check:d,max_peers_overall_input:s,max_peers_per_torrent_input:r,pex_check:l,root:e}}static _createNetworkPage(){let e=document.createElement("div");e.classList.add("prefs-network-page");let t=document.createElement("div");t.textContent="Listening Port",t.classList.add("section-label"),e.append(t),t=document.createElement("label"),t.textContent="Peer listening port:",e.append(t);let o=document.createElement("input");o.type="number",o.dataset.key="peer_port",o.id=v(),t.setAttribute("for",o.id),e.append(o);let r=o,s=document.createElement("div");s.classList.add("port-status"),t=document.createElement("label"),t.textContent="IPv4 port is",s.append(t);let i=document.createElement("label");i.textContent="?",i.classList.add("port-status-label"),s.append(i),s.append(document.createElement("br")),t=document.createElement("label"),t.textContent="IPv6 port is",s.append(t);let a=document.createElement("label");a.textContent="?",a.classList.add("port-status-label"),s.append(a),e.append(s);let c=n._createCheckAndLabel("randomize-port","Randomize port on launch");c.check.dataset.key="peer_port_random_on_start",e.append(c.root);let l=c.check;c=n._createCheckAndLabel("port-forwarding","Use port forwarding from my router"),c.check.dataset.key="port_forwarding_enabled",e.append(c.root);let u=c.check;t=document.createElement("div"),t.textContent="Options",t.classList.add("section-label"),e.append(t),c=n._createCheckAndLabel("utp-enabled","Enable uTP for peer communication"),c.check.dataset.key="utp_enabled",e.append(c.root);let d=c.check;t=document.createElement("div"),t.textContent="Default Public Trackers",t.classList.add("section-label"),e.append(t);let g=["Trackers to use on all public torrents.","To add a backup URL, add it on the next line after a primary URL.","To add a new primary URL, add it after a blank line."];for(let G of g)t=document.createElement("label"),t.classList.add("default-trackers-label"),t.textContent=G,t.setAttribute("for","default-trackers"),e.append(t);let m=document.createElement("textarea");return m.dataset.key="default_trackers",m.id="default-trackers",e.append(m),{default_trackers_textarea:m,port_forwarding_check:u,port_input:r,port_status_label:{ipv4:i,ipv6:a},random_port_check:l,root:e,utp_check:d}}static _create(){let e={network:n._createNetworkPage(),peers:n._createPeersPage(),speed:n._createSpeedPage(),torrents:n._createTorrentsPage()};return{...M("prefs-dialog",[["prefs-tab-torrent",e.torrents.root,"Torrents"],["prefs-tab-speed",e.speed.root,"Speed"],["prefs-tab-peers",e.peers.root,"Peers"],["prefs-tab-network",e.network.root,"Network"]]),...e}}constructor(e,t){super(),this.closed=!1,this.session_manager=e,this.remote=t,this.update_from_session=()=>this._update(),this.elements=n._create(),this.elements.peers.blocklist_update_button.addEventListener("click",s=>{b(s.target,"Updating blocklist..."),this.remote.updateBlocklist(),this._setBlocklistButtonEnabled(!1)}),this.elements.torrents.register_handler_button.addEventListener("click",s=>{n._toggleProtocolHandler(s.currentTarget)}),this.elements.dismiss.addEventListener("click",()=>this.close()),this.outside=new _(this.elements.root),this.outside.addEventListener("click",()=>this.close()),Object.seal(this);let o=this._onControlChanged.bind(this),r=s=>{for(let i of Object.values(s))if(i.tagName==="INPUT")switch(i.type){case"checkbox":case"radio":case"number":case"text":case"url":i.addEventListener("change",o);break;default:console.trace(`unhandled input: ${i.type}`);break}else(i.tagName==="TEXTAREA"||i.tagName==="SELECT")&&i.addEventListener("change",o)};r(this.elements.network),r(this.elements.peers),r(this.elements.speed),r(this.elements.torrents),this.session_manager.addEventListener("session-change",this.update_from_session),this.update_from_session(),document.body.append(this.elements.root)}close(){if(!this.closed){this.outside.stop(),this.session_manager.removeEventListener("session-change",this.update_from_session),this.elements.root.remove(),this.dispatchEvent(new Event("close"));for(let e of Object.keys(this))this[e]=null;this.closed=!0}}};var ne=class n extends EventTarget{constructor(e){super(),this.options=e,this.options.trash=!1,this.elements=n._create(e),this.elements.dismiss.addEventListener("click",()=>this._onDismiss()),this.elements.confirm.addEventListener("click",()=>this._onConfirm()),document.body.append(this.elements.root),this.elements.dismiss.focus()}close(){if(!this.closed){this.elements.root.remove(),this.dispatchEvent(new Event("close"));for(let e of Object.keys(this))delete this[e];this.closed=!0}}_onDismiss(){this.close()}_onConfirm(){let{remote:e,torrents:t,trash:o}=this.options;t.length>0&&e.removeTorrents(t,o),this.close()}static _create(e){let{torrents:t}=e,o=X("remove-dialog"),{confirm:r,heading:s,message:i,workarea:a}=o;s.textContent=t.length===1?`Remove ${t[0].getName()}?`:`Remove ${t.length} transfers?`;let c=document.createElement("input");c.id="delete-local-data-check",c.type="checkbox",c.checked=!1,i.append(c);let l=document.createElement("label");l.id="delete-local-data-label",l.setAttribute("for",c.id),l.textContent="Delete downloaded data",i.append(l);let u=document.createElement("div"),d=g=>{g&&t.length===1?u.textContent="All data downloaded for this torrent will be deleted. Are you sure you want to remove it?":g?u.textContent="All data downloaded for these torrents will be deleted. Are you sure you want to remove them?":t.length===1?u.textContent="Once removed, continuing the transfer will require the torrent file. Are you sure you want to remove it?":u.textContent="Once removed, continuing the transfers will require the torrent files. Are you sure you want to remove them?",r.textContent=g?"Delete":"Remove"};return d(c.checked),c.addEventListener("click",()=>{e.trash=c.checked,d(c.checked)}),a.append(u),o}};var ae=class n extends EventTarget{constructor(e,t){super(),this.controller=e,this.remote=t,this.elements={},this.torrents=[],this.show()}show(){let e=this.controller.getSelectedTorrents();if(e.length!==1){console.trace();return}let{handler:t}=this.controller;this.torrents=e,this.elements=n._create(),this.elements.dismiss.addEventListener("click",()=>this._onDismiss()),this.elements.confirm.addEventListener("click",()=>this._onConfirm()),this.elements.entry.value=t===null?e[0].getName():t.subtree.name,document.body.append(this.elements.root),this.elements.entry.focus()}close(){let{handler:e}=this.controller;e&&e.classList.remove("selected"),this.elements.root.remove(),this.dispatchEvent(new Event("close")),delete this.remote,delete this.elements,delete this.torrents}_onDismiss(){this.close()}_onConfirm(){let{handler:e}=this.controller,[t]=this.torrents,o=e?e.file_path:t.getName(),r=this.elements.entry.value;this.remote.renameTorrent([t.getId()],o,r,s=>{if("result"in s){let i=s.result;if(e)if(e.subtree.name=i.name,b(e.name_container,i.name),e.subdir){let a=t.getIndividualFile(o);if(a){let c=a.name.slice(0,Math.max(0,a.name.lastIndexOf("/")+1));a.name=`${c}${i.name}`}}else t.refresh(i);else t.refresh(i)}else{let i=s.error,a=i.data?.errorString??i.message??"",c=new k({heading:`Error renaming "${o}"`,message:`${a} (${i.code}`});this.controller.setCurrentPopup(c)}delete this.controller}),this.close()}static _create(){let e=X("rename-dialog");e.root.setAttribute("aria-label","Rename Torrent"),e.heading.textContent="Enter new name:",e.confirm.textContent="Rename";let t=document.createElement("label");t.setAttribute("for","torrent-rename-name"),t.textContent="Enter new name:",e.workarea.append(t);let o=document.createElement("input");return o.setAttribute("type","text"),o.id="torrent-rename-name",e.entry=o,e.workarea.append(o),e}};var ce=class n extends EventTarget{constructor(e,t){super(),this.controller=e,this.remote=t,this.elements={},this.torrents=[],this.show()}show(){let e=this.controller.getSelectedTorrents();if(e.length===0){console.error("At least one selected torrent expected.");return}let[t]=e;this.torrents=e,this.elements=n._create(),this.elements.dismiss.addEventListener("click",()=>this._onDismiss()),this.elements.confirm.addEventListener("click",()=>this._onConfirm()),this.elements.entry.value=t.getLabels().join(", "),document.body.append(this.elements.root),this.elements.entry.focus()}close(){this.elements.root.remove(),this.dispatchEvent(new Event("close")),delete this.elements,delete this.torrents}_onDismiss(){this.close()}_onConfirm(){let{torrents:e}=this,{remote:t}=this,o=e.map(c=>c.getId()),{elements:r}=this,{entry:s}=r,{value:i}=s,a=i.split(",").map(c=>c.trim()).filter(c=>c.length>0);t.setLabels(o,a,c=>{if(c.result==="success")for(let l of e)l.refresh({labels:a})}),this.close()}static _create(){let e=X("labels-dialog");e.root.setAttribute("aria-label","Edit Labels"),e.heading.textContent="Edit Labels:",e.confirm.textContent="Save";let t=document.createElement("label");t.setAttribute("for","torrent-labels"),t.textContent="Labels:",e.workarea.append(t);let o=document.createElement("input");return o.setAttribute("type","text"),o.id="torrent-labels",e.entry=o,e.workarea.append(o),e}};var le=class n extends EventTarget{constructor(e){super(),this.elements=n._create(e),this.elements.dismiss.addEventListener("click",()=>this._onDismiss()),document.body.append(this.elements.root),this.elements.dismiss.focus()}close(){this.elements.root.remove(),this.dispatchEvent(new Event("close")),delete this.elements}_onDismiss(){this.close()}static _create(e){let t=X("shortcuts-dialog");t.root.setAttribute("aria-label","Keyboard Shortcuts");let o=document.createElement("table"),r=document.createElement("thead");o.append(r);let s=document.createElement("tr");r.append(s);let i=document.createElement("th");i.textContent="Key",s.append(i),i=document.createElement("th"),i.textContent="Action",s.append(i);let a=document.createElement("tbody");o.append(a);let c={};for(let[l,u]of e.allShortcuts().entries()){let d=l.split("+"),g=[d.pop(),...d].join("+");c[g]={name:u,shortcut:l}}for(let[,l]of Object.entries(c).toSorted()){let{name:u,shortcut:d}=l;s=document.createElement("tr"),a.append(s);let g=document.createElement("td");g.textContent=d.replaceAll("+"," + "),s.append(g),g=document.createElement("td"),g.textContent=e.text(u),s.append(g)}return t.heading.textContent="Transmission",t.dismiss.textContent="Close",t.heading.textContent="Keyboard shortcuts",t.message.append(o),t.confirm.remove(),delete t.confirm,t}};var de=class n extends EventTarget{constructor(e){super(),this.remote=e;let t=()=>this.remote.loadDaemonStats(r=>this._update(r.result)),o=5e3;this.interval=setInterval(t,o),t(),this.elements=n._create(),this.elements.dismiss.addEventListener("click",()=>this._onDismiss()),document.body.append(this.elements.root),this.elements.dismiss.focus()}close(){if(!this.closed){clearInterval(this.interval),this.elements.root.remove(),this.dispatchEvent(new Event("close"));for(let e of Object.keys(this))delete this[e];this.closed=!0}}_onDismiss(){this.close()}_update(e){console.log(e);let t=x,o=e.current_stats,r=S.ratio(o.uploaded_bytes,o.downloaded_bytes);b(this.elements.session.up,t.size(o.uploaded_bytes)),b(this.elements.session.down,t.size(o.downloaded_bytes)),this.elements.session.ratio.innerHTML=t.ratioString(r),b(this.elements.session.time,t.timeInterval(o.seconds_active)),o=e.cumulative_stats,r=S.ratio(o.uploaded_bytes,o.downloaded_bytes),b(this.elements.total.up,t.size(o.uploaded_bytes)),b(this.elements.total.down,t.size(o.downloaded_bytes)),this.elements.total.ratio.innerHTML=t.ratioString(r),b(this.elements.total.time,t.timeInterval(o.seconds_active))}static _create(){let e=X("statistics-dialog"),{confirm:t,dismiss:o,heading:r,root:s,workarea:i}=e;t.remove(),o.textContent="Close",delete e.confirm;let a="Statistics";s.setAttribute("aria-label",a),r.textContent=a;let c=["Uploaded:","Downloaded:","Ratio:","Running time:"],l=be("Current session",c),[u,d,g,m]=l.children,I=e.session={};I.up=u,I.down=d,I.ratio=g,I.time=m,i.append(l.root),l=be("Total",c);let[G,f,C,h]=l.children,y=e.total={};return y.up=G,y.down=f,y.ratio=C,y.time=h,i.append(l.root),e}};var F={formatETA:n=>{let e=n.getETA();return e<0||e>=999*60*60?"":`ETA: ${x.timeInterval(e,1)}`},formatLabels:(n,e)=>{let t=n.getLabels();e.innerHTML="";for(let o of t){let r=document.createElement("span");r.classList.add("torrent-label"),r.textContent=o,e.append(r)}},getProgressInfo:(n,e)=>{let t=e.getStatus(),o=["torrent-progress-bar"],r=100,s=null;if(t===A._StatusStopped&&o.push("paused"),e.needsMetaData())o.push("magnet"),r=e.getMetadataPercentComplete()*100;else if(t===A._StatusCheck)o.push("verify"),r=e.getRecheckProgress()*100;else if(e.getLeftUntilDone()>0)o.push("leech"),r=e.getPercentDone()*100;else if(o.push("seed"),t!==A._StatusStopped){let i=e.seedRatioLimit(n);s=i>0?e.getUploadRatio()*100/i:100}return e.isQueued()&&o.push("queued"),{classList:o,percent:r,ratio:s}},renderProgressbar:(n,e,t)=>{let o=F.getProgressInfo(n,e),r=Math.min(o.ratio||o.percent,100),s=`${x.percentString(r,2)}%`;t.className=o.classList.join(" "),t.style.setProperty("--progress",s),t.dataset.progress=o.ratio?"100%":s},symbol:{down:"\u25BC",up:"\u25B2"},updateIcon:(n,e)=>{n.dataset.iconMimeType=e.getPrimaryMimeType().split("/",1).pop(),n.dataset.iconMultifile=e.getFileCount()>1?"true":"false"}},ge=class n{static renderPeerDetails(e,t){let o=x,r=e.getError()!==A._ErrNone;t.classList.toggle("error",r);let s=e.getErrorMessage();if(s)b(t,s);else if(e.isDownloading()){let i=e.getPeersConnected(),a=e.getWebseedsSendingToUs(),c=["Downloading from"];i&&(c.push(e.getPeersSendingToUs(),"of",o.countString("peer","peers",i)),a&&c.push("and")),a&&c.push(o.countString("web seed","web seeds",a)),c.push("-",F.symbol.down,o.speedBps(e.getDownloadSpeed()),F.symbol.up,o.speedBps(e.getUploadSpeed())),b(t,c.join(" "))}else if(e.isSeeding()){let i=["Seeding to",e.getPeersGettingFromUs(),"of",o.countString("peer","peers",e.getPeersConnected()),"-",F.symbol.up,o.speedBps(e.getUploadSpeed())].join(" ");b(t,i)}else if(e.isChecking()){let i=["Verifying local data (",o.percentString(100*e.getRecheckProgress(),1),"% tested)"].join("");b(t,i)}else b(t,e.getStateString())}static renderProgressDetails(e,t,o){let r=x;if(t.needsMetaData()){let l="retrieving";t.isStopped()&&(l="needs");let u=100*t.getMetadataPercentComplete(),d=["Magnetized transfer - ",l," metadata (",r.percentString(u,1),"%)"].join("");b(o,d);return}let s=t.getSizeWhenDone(),i=t.getTotalSize(),a=t.isDone()||t.isSeeding(),c=[];if(a?(i===s?c.push(r.size(i)):c.push(r.size(s)," of ",r.size(t.getTotalSize())," (",t.getPercentDoneStr(),"%)"),c.push(", uploaded ",r.size(t.getUploadedEver())," (Ratio: ",r.ratioString(t.getUploadRatio()),")")):c.push(r.size(s-t.getLeftUntilDone())," of ",r.size(s)," (",t.getPercentDoneStr(),"%)"),!t.isStopped()&&(!a||t.seedRatioLimit(e)>0)){c.push(" - ");let l=t.getETA();l<0||l>=999*60*60?c.push("remaining time unknown"):c.push(r.timeInterval(t.getETA(),1)," remaining")}b(o,c.join(""))}render(e,t,o){let r=t.isStopped();o.classList.toggle("paused",r);let{labels:s,name:i,peer_details:a,progressbar:c,progress_details:l}=o;b(i,t.getName()),F.formatLabels(t,s),n.renderProgressDetails(e,t,l),F.renderProgressbar(e,t,c),n.renderPeerDetails(t,a)}createRow(e){let t=document.createElement("li");t.className="torrent";let o=[["icon","icon"],["name","torrent-name"],["labels","torrent-labels"],["progress_details","torrent-progress-details"],["progressbar","torrent-progress-bar"],["peer_details","torrent-peer-details"]];for(let[r,s]of o){let i=document.createElement("div");i.className=s,t.append(i),t[r]=i}return F.updateIcon(t.icon,e),t}},pe=class n{static renderPeerDetails(e,t){let o=x,r=e.getError()!==A._ErrNone;t.classList.toggle("error",r);let s=e.getErrorMessage();if(s)b(t,s);else if(e.isDownloading()){let i=e.getDownloadSpeed()>0,a=e.getUploadSpeed()>0;if(!a&&!i)b(t,"Idle");else{let c=[F.formatETA(e)];i&&c.push(F.symbol.down,o.speedBps(e.getDownloadSpeed())),a&&c.push(F.symbol.up,o.speedBps(e.getUploadSpeed())),b(t,c.join(" "))}}else if(e.isSeeding()){let i=["Ratio:",o.ratioString(e.getUploadRatio()),"-",F.symbol.up,o.speedBps(e.getUploadSpeed())].join(" ");b(t,i)}else b(t,e.getStateString())}render(e,t,o){o.classList.toggle("paused",t.isStopped());let{labels:r,name:s,peer_details:i,progressbar:a}=o;b(s,t.getName()),F.formatLabels(t,r),n.renderPeerDetails(t,i),F.renderProgressbar(e,t,a),a.classList.add("compact")}createRow(e){let t=document.createElement("li");t.className="torrent compact";let o=[["icon","icon"],["name","torrent-name compact"],["labels","torrent-labels compact"],["peer_details","torrent-peer-details compact"],["progressbar","torrent-progress-bar compact"]];for(let[r,s]of o){let i=document.createElement("div");i.className=s,t.append(i),t[r]=i}return F.updateIcon(t.icon,e),t}},ue=class{constructor(e,t,o){this._view=e,this._torrent=o,this._element=e.createRow(o);let r=()=>this.render(t);this._torrent.addEventListener("dataChanged",r),r()}getElement(){return this._element}render(e){let t=this.getTorrent();t&&this._view.render(e,t,this.getElement())}isSelected(){return this.getElement().classList.contains("selected")}getTorrent(){return this._torrent}getTorrentId(){return this.getTorrent().getId()}};var me=class n extends EventTarget{constructor(e,t,o){super(),this.action_manager=e,this.handler=null,this.notifications=t,this.prefs=o,this.remote=new E(this),this.speed={down:document.querySelector("#speed-down"),up:document.querySelector("#speed-up")};for(let[a,c]of[["#toolbar-open","open"],["#toolbar-delete","delete"],["#toolbar-start","start"],["#toolbar-pause","pause"],["#toolbar-inspector","inspector"],["#toolbar-overflow","overflow"]])document.querySelector(a).prepend(K[c](),document.createElement("BR"));document.querySelector(".speed-container").append(K.speedDown()),document.querySelector(".speed-container + .speed-container").append(K.speedUp()),this.addEventListener("torrent-selection-changed",a=>this.action_manager.update(a)),this.filterText="",this._torrents={},this._rows=[],this.oldTrackers=[],this.dirtyTorrents=new Set,this.changeStatus=!1,this.refilterSoon=R(()=>this._refilter(!1)),this.refilterAllSoon=R(()=>this._refilter(!0)),this.pointer_device=Object.seal({is_touch_device:"ontouchstart"in globalThis,long_press_callback:null,x:0,y:0}),this.popup=Array.from({length:n.max_popups}).fill(null),this.busytyping=!1;for(let a of document.querySelectorAll("button[data-action]")){let{action:c}=a.dataset;w(a,this.action_manager.isEnabled(c)),a.addEventListener("click",()=>{this.action_manager.click(c)})}document.querySelector("#filter-tracker").addEventListener("change",a=>{this.setFilterTracker(a.target.value)}),this.action_manager.addEventListener("change",a=>{for(let c of document.querySelectorAll(`[data-action="${a.action}"]`))w(c,a.enabled)}),this.action_manager.addEventListener("click",a=>{switch(a.action){case"copy-name":navigator.clipboard?navigator.clipboard.writeText(this.handler.subtree.name):prompt("Select all then copy",this.handler.subtree.name),this.handler.classList.remove("selected");break;case"deselect-all":this._deselectAll();break;case"move-bottom":this._moveBottom();break;case"move-down":this._moveDown();break;case"move-top":this._moveTop();break;case"move-up":this._moveUp();break;case"open-torrent":this.setCurrentPopup(new V(this,this.remote));break;case"pause-all-torrents":this._stopTorrents(this._getAllTorrents());break;case"pause-selected-torrents":this._stopTorrents(this.getSelectedTorrents());break;case"reannounce-selected-torrents":this._reannounceTorrents(this.getSelectedTorrents());break;case"remove-selected-torrents":this._removeSelectedTorrents();break;case"resume-selected-torrents":this._startSelectedTorrents(!1);break;case"resume-selected-torrents-now":this._startSelectedTorrents(!0);break;case"select-all":this._selectAll();break;case"show-about-dialog":this.setCurrentPopup(new ee(this.version_info));break;case"show-inspector":this.popup[0]instanceof D?this.popup[0].close():this.setCurrentPopup(new D(this),0);break;case"show-move-dialog":this.setCurrentPopup(new re(this,this.remote));break;case"show-overflow-menu":this.popup[n.default_popup_level]instanceof J?this.popup[n.default_popup_level].close():this.setCurrentPopup(new J(this,this.prefs,this.remote,this.action_manager));break;case"show-preferences-dialog":this.setCurrentPopup(new ie(this,this.remote),0);break;case"show-shortcuts-dialog":this.setCurrentPopup(new le(this.action_manager));break;case"show-statistics-dialog":this.setCurrentPopup(new de(this.remote));break;case"show-rename-dialog":this.setCurrentPopup(new ae(this,this.remote));break;case"show-labels-dialog":this.setCurrentPopup(new ce(this,this.remote));break;case"start-all-torrents":this._startTorrents(this._getAllTorrents());break;case"toggle-compact-rows":this.prefs.display_mode=this.prefs.display_mode===p.DisplayCompact?p.DisplayFull:p.DisplayCompact;break;case"verify-selected-torrents":this._verifyTorrents(this.getSelectedTorrents());break;default:console.warn(`unhandled action: ${a.action}`)}});let r=document.querySelector("#filter-mode");N(r,null,[["All",p.FilterAll]]),N(r,"status",[["Active",p.FilterActive],["Downloading",p.FilterDownloading],["Seeding",p.FilterSeeding],["Paused",p.FilterPaused],["Finished",p.FilterFinished],["Error",p.FilterError]]),N(r,"list",[["Private torrents",p.FilterPrivate],["Public torrents",p.FilterPublic]]),r.value=this.prefs.filter_mode,r.addEventListener("change",a=>{this.prefs.filter_mode=a.target.value,this.refilterAllSoon()}),r=document.querySelector("#filter-tracker"),N(r,null,[["All",p.FilterAll]]);let s=document.querySelector("#torrent-search");r=document.querySelector("#reset"),r.addEventListener("click",()=>{s.value="",this._setFilterText(s.value),this.refilterAllSoon()}),s.value.trim()&&(this.filterText=s.value,r.style.display="block",this.refilterAllSoon()),r=document.querySelector("#turtle"),r.addEventListener("click",a=>{this.remote.savePrefs({[B._TurtleState]:!a.target.classList.contains("alt-speed-enabled")})}),document.addEventListener("keydown",this._keyDown.bind(this)),document.addEventListener("keyup",this._keyUp.bind(this)),r=document.querySelector("#torrent-container"),r.addEventListener("click",a=>{this.popup[n.default_popup_level]&&this.setCurrentPopup(null),a.target===a.currentTarget&&this._deselectAll()}),r.addEventListener("dblclick",()=>{(!this.popup[0]||this.popup[0].name!=="inspector")&&this.action_manager.click("show-inspector")}),r.addEventListener("dragenter",n._dragenter),r.addEventListener("dragover",n._dragenter),r.addEventListener("drop",this._drop.bind(this)),this._setupSearchBox(),this.elements={torrent_list:document.querySelector("#torrent-list")};let i=a=>{let c=a.target;for(;c&&!c.classList.contains("torrent");)c=c.parentNode;let l=this._rows.find(u=>u.getElement()===c);l&&!l.isSelected()&&this._setSelectedRow(l),this.handler&&(this.handler.classList.remove("selected"),this.handler=null),this.context_menu("#torrent-container"),a.preventDefault()};this.pointer_event(this.elements.torrent_list,i),this.loadDaemonPrefs(),this._initializeTorrents(),this.refreshTorrents(),this.togglePeriodicSessionRefresh(!0),this.prefs.addEventListener("change",({key:a,value:c})=>this._onPrefChanged(a,c));for(let[a,c]of this.prefs.entries())this._onPrefChanged(a,c)}_openTorrentFromUrl(){setTimeout(()=>{let e=new URLSearchParams(globalThis.location.search).get("addtorrent");if(e){this.setCurrentPopup(new V(this,this.remote,e));let t=new URL(globalThis.location);t.search="",globalThis.history.pushState("","",t.toString())}},0)}loadDaemonPrefs(){this.remote.loadDaemonPrefs(e=>{this.session_properties=e.result,this._openTorrentFromUrl()})}get session_properties(){return this._session_properties}set session_properties(e){if(P(this._session_properties,e))return;this._session_properties=Object.seal(e);let t=new Event("session-change");t.session_properties=e,this.dispatchEvent(t),this._updateGuiFromSession(e)}_setupSearchBox(){let e=document.querySelector("#torrent-search"),t="blur";e.classList.add(t),e.addEventListener("blur",()=>e.classList.add(t)),e.addEventListener("focus",()=>e.classList.remove(t)),e.addEventListener("input",()=>{e.value.trim()!==this.filterText&&this._setFilterText(e.value)})}_onPrefChanged(e,t){switch(e){case p.DisplayMode:{this.torrentRenderer=t==="compact"?new pe:new ge,this.refilterAllSoon();break}case p.ContrastMode:{document.body.classList.remove("contrast-more","contrast-less"),document.body.classList.add(`contrast-${t}`);break}case p.FilterMode:case p.SortDirection:case p.SortMode:this.refilterAllSoon();break;case p.RefreshRate:{clearInterval(this.refreshTorrentsInterval);let o=this.refreshTorrents.bind(this),r=this.prefs.refresh_rate_sec,s=r>0?r*1e3:1e3;this.refreshTorrentsInterval=setInterval(o,s);break}default:break}}context_menu(e,t){let o=new te(this,t);this.setCurrentPopup(o);let r=document.querySelector(e).getBoundingClientRect(),s=Math.min(this.pointer_device.x,r.right+globalThis.scrollX-o.root.clientWidth),i=Math.min(this.pointer_device.y,r.bottom+globalThis.scrollY-o.root.clientHeight);o.root.style.left=`${Math.max(s,0)}px`,o.root.style.top=`${Math.max(i,0)}px`}pointer_event(e,t){if(this.pointer_device.is_touch_device){let o=this.pointer_device;e.addEventListener("touchstart",r=>{o.x=r.touches[0].pageX,o.y=r.touches[0].pageY,o.long_press_callback?(clearTimeout(o.long_press_callback),o.long_press_callback=null):o.long_press_callback=setTimeout(()=>{r.touches.length===1&&t(r)},500)}),e.addEventListener("touchend",()=>{clearTimeout(o.long_press_callback),o.long_press_callback=null,setTimeout(()=>{let r=this.popup[n.default_popup_level];r&&(r.root.style.pointerEvents="auto")},1)}),e.addEventListener("touchmove",r=>{o.x=r.touches[0].pageX,o.y=r.touches[0].pageY,clearTimeout(o.long_press_callback),o.long_press_callback=null}),e.addEventListener("contextmenu",r=>{r.preventDefault()})}else e.addEventListener("mousemove",o=>{this.pointer_device.x=o.pageX,this.pointer_device.y=o.pageY}),e.addEventListener("contextmenu",o=>{t(o);let r=this.popup[n.default_popup_level];r&&(r.root.style.pointerEvents="auto")})}static get max_popups(){return 2}static get default_popup_level(){return n.max_popups-1}_getAllTorrents(){return Object.values(this._torrents)}static _getTorrentIds(e){return e.map(t=>t.getId())}seedRatioLimit(){let e=this.session_properties;return e&&e.seed_ratio_limited?e.seed_ratio_limit:-1}_getSelectedRows(){return this._rows.filter(e=>e.isSelected())}getSelectedTorrents(){return this._getSelectedRows().map(e=>e.getTorrent())}_getSelectedTorrentIds(){return n._getTorrentIds(this.getSelectedTorrents())}_setSelectedRow(e){let t=e?e.getElement():null;for(let o of this.elements.torrent_list.children)o.classList.toggle("selected",o===t);this._dispatchSelectionChanged()}_selectRow(e){e.getElement().classList.add("selected"),this._dispatchSelectionChanged()}_deselectRow(e){e.getElement().classList.remove("selected"),this._dispatchSelectionChanged()}_selectAll(){for(let e of this.elements.torrent_list.children)e.classList.add("selected");this._dispatchSelectionChanged()}_deselectAll(){for(let e of this.elements.torrent_list.children)e.classList.remove("selected");this._dispatchSelectionChanged(),delete this._last_torrent_clicked}_indexOfLastTorrent(){return this._rows.findIndex(e=>e.getTorrentId()===this._last_torrent_clicked)}_selectRange(e){let t=this._indexOfLastTorrent();if(t===-1)this._selectRow(e);else{let o=this._rows.indexOf(e),r=Math.min(t,o),s=Math.max(t,o);for(let i=r;i<=s;++i)this._selectRow(this._rows[i])}this._dispatchSelectionChanged()}_dispatchSelectionChanged(){let e=[],t=[];for(let r of this._rows)(r.isSelected()?t:e).push(r.getTorrent());let o=new Event("torrent-selection-changed");o.nonselected=e,o.selected=t,this.dispatchEvent(o)}static _createKeyShortcutFromKeyboardEvent(e){let t=[];return e.ctrlKey&&t.push("Control"),e.altKey&&t.push("Alt"),e.metaKey&&t.push("Meta"),e.shiftKey&&t.push("Shift"),t.push(e.key.length===1?e.key.toUpperCase():e.key),t.join("+")}_keyDown(e){let{ctrlKey:t,keyCode:o,metaKey:r,shiftKey:s,target:i}=e,a=["INPUT","TEXTAREA"].includes(i.tagName);if(!a){let d=n._createKeyShortcutFromKeyboardEvent(e),g=this.action_manager.getActionForShortcut(d);if(g){e.preventDefault(),this.action_manager.click(g);return}}if(o===27&&this.popup.some(Boolean)){this.setCurrentPopup(null,0),e.preventDefault();return}let l=document.querySelector(".popup:not(.hidden)"),u=this._rows;if(!a&&!l&&!r&&!t){let d=o===16,g=o===38,m=o===40;if((g||m)&&u.length>0){let I=this._indexOfLastTorrent(),G=this._shift_index,f=0,C=u.length-1,h=I;m&&h+1<=C?++h:g&&h-1>=f&&--h;let y=u[h];G>=0?G<=I&&I=I&&I>h?this._selectRow(y):(G>=I&&h>I||G<=I&&I>h)&&this._deselectRow(u[I]):s?this._selectRange(y):this._setSelectedRow(y),y&&(this._last_torrent_clicked=y.getTorrentId(),y.getElement().scrollIntoView(),e.preventDefault())}else d&&(this._shift_index=this._indexOfLastTorrent())}}_keyUp(e){e.keyCode===16&&delete this._shift_index}static _dragenter(e){if(e.dataTransfer&&e.dataTransfer.types){let t=new Set(["text/uri-list","text/plain"]);if(e.dataTransfer.types.some(o=>t.has(o))||e.dataTransfer.types.includes("Files"))return e.stopPropagation(),e.preventDefault(),e.dataTransfer.dropEffect="copy",!1}else e.dataTransfer&&(e.dataTransfer.dropEffect="none");return!0}static _isValidURL(e){try{return!!new URL(e)}catch{return!1}}shouldAddedTorrentsStart(){return this.session_properties.start_added_torrents}_drop(e){let t=!this.shouldAddedTorrentsStart();if(!e.dataTransfer||!e.dataTransfer.types)return!0;let o=e.dataTransfer.types.findLast(s=>["text/uri-list","text/plain"].includes(s));for(let s of e.dataTransfer.getData(o).split(` +`).map(i=>i.trim()).filter(i=>n._isValidURL(i)))this.remote.addTorrentByUrl(s,t);let{files:r}=e.dataTransfer;return r.length>0&&this.setCurrentPopup(new V(this,this.remote,"",r)),e.preventDefault(),!1}togglePeriodicSessionRefresh(e){!e&&this.sessionInterval&&(clearInterval(this.sessionInterval),delete this.sessionInterval),e&&(this.loadDaemonPrefs(),this.sessionInterval||(this.sessionInterval=setInterval(this.loadDaemonPrefs.bind(this),8e3)))}_setFilterText(e){clearTimeout(this.busytyping),this.busytyping=setTimeout(()=>{this.busytyping=!1,this.filterText=e.trim(),this.refilterAllSoon()},e?250:0)}_onTorrentChanged(e){this.changeStatus&&(this._dispatchSelectionChanged(),this.changeStatus=!1);let t=e.currentTarget;this.dirtyTorrents.add(t.getId()),this.refilterSoon()}updateTorrents(e,t){this.remote.updateTorrents(e,t,(o,r)=>{let s=[],i=o.shift(),a={};for(let c of o){for(let[d,g]of i.entries())a[g]=c[d];let{id:l}=a,u=this._torrents[l];if(u){let d=u.needsMetaData();u.refresh(a),d&&!u.needsMetaData()&&s.push(l)}else u=this._torrents[l]=new A(a),u.addEventListener("dataChanged",this._onTorrentChanged.bind(this)),this.dirtyTorrents.add(l),(!("name"in u.fields)||!("status"in u.fields))&&s.push(l)}if(s.length>0){let c=["id",...A.Fields.Metadata,...A.Fields.Stats];this.updateTorrents(s,c),this.refilterSoon()}r&&(this._deleteTorrents(r),this.refilterSoon())})}refreshTorrents(){let e=["id",...A.Fields.Stats];this.updateTorrents("recently_active",e)}_initializeTorrents(){let e=["id",...A.Fields.Metadata,...A.Fields.Stats];this.updateTorrents(null,e)}_onRowClicked(e){let t=e.metaKey||e.ctrlKey,{row:o}=e.currentTarget;this.popup[n.default_popup_level]&&this.setCurrentPopup(null),e.stopPropagation(),e.shiftKey?(this._selectRange(o),globalThis.focus()):!o.isSelected()&&t?this._selectRow(o):o.isSelected()?o.isSelected()&&t?this._deselectRow(o):o.isSelected()&&this._setSelectedRow(o):this._setSelectedRow(o),this._last_torrent_clicked=o.getTorrentId()}_deleteTorrents(e){if(e&&e.length>0){for(let t of e)this.dirtyTorrents.add(t),delete this._torrents[t];this.refilterSoon()}}_removeSelectedTorrents(){let e=this.getSelectedTorrents();e.length>0&&this.setCurrentPopup(new ne({remote:this.remote,torrents:e}))}_startSelectedTorrents(e){this._startTorrents(this.getSelectedTorrents(),e)}_startTorrents(e,t){this.changeStatus=!0,this.remote.startTorrents(n._getTorrentIds(e),t,this.refreshTorrents,this)}_verifyTorrents(e){this.remote.verifyTorrents(n._getTorrentIds(e),this.refreshTorrents,this)}_reannounceTorrents(e){this.remote.reannounceTorrents(n._getTorrentIds(e),this.refreshTorrents,this)}_stopTorrents(e){this.changeStatus=!0,this.remote.stopTorrents(n._getTorrentIds(e),()=>{setTimeout(()=>{this.refreshTorrents()},500)},this)}changeFileCommand(e,t,o){this.remote.changeFileCommand(e,t,o)}_moveTop(){this.remote.moveTorrentsToTop(this._getSelectedTorrentIds(),this.refreshTorrents,this)}_moveUp(){this.remote.moveTorrentsUp(this._getSelectedTorrentIds(),this.refreshTorrents,this)}_moveDown(){this.remote.moveTorrentsDown(this._getSelectedTorrentIds(),this.refreshTorrents,this)}_moveBottom(){this.remote.moveTorrentsToBottom(this._getSelectedTorrentIds(),this.refreshTorrents,this)}_updateGuiFromSession(e){let[,t,o]=e.version.match(/^(.*)\s\(([\da-f]+)\)/);this.version_info={checksum:o,version:t},document.querySelector("#turtle").classList.toggle("alt-speed-enabled",e[B._TurtleState])}_updateStatusbar(){let e=x,t=this._getAllTorrents(),o=t.reduce((i,a)=>i+a.getUploadSpeed(),0),r=t.reduce((i,a)=>i+a.getDownloadSpeed(),0),s=e.countString("Transfer","Transfers",this._rows.length);b(this.speed.down,e.speedBps(r)),b(this.speed.up,e.speedBps(o)),b(document.querySelector("#filter-count"),s)}static _displayName(e){let t=e;return t.length>0&&(t=t.charAt(0).toUpperCase()+t.slice(1)),t}_updateFilterSelect(){let e=this._getTrackerCounts(),t=Object.keys(e).toSorted();if(t.length!==this.oldTrackers.length||t.some((o,r)=>o!==this.oldTrackers[r])){this.oldTrackers=t;let o=[["All",p.FilterAll,!this.filterTracker],...t.map(s=>[n._displayName(s),s,s===this.filterTracker])],r=document.querySelector("#filter-tracker");for(;r.firstChild;)r.lastChild.remove();N(r,null,o)}}sortRows(e){let t=e.map(r=>r.getTorrent()),o=e.reduce((r,s)=>(r[s.getTorrent().getId()]=s,r),{});A.sortTorrents(t,this.prefs.sort_mode,this.prefs.sort_direction);for(let[r,s]of t.entries())e[r]=o[s.getId()]}_refilter(e){let{sort_mode:t,sort_direction:o,filter_mode:r}=this.prefs,s=this.filterTracker,i=this.torrentRenderer,a=this.elements.torrent_list,c=null,l=null,u=/^labels:([\w,-\s]*)(.*)$/.exec(this.filterText);u?(c=u[2].trim(),l=u[1].split(",")):(c=this.filterText,l=[]);let d=()=>[...a.children].length,g=()=>[...a.children].reduce((Z,L)=>Z+L.classList.contains("selected")?1:0,0),m=d(),I=g();if(this._updateFilterSelect(),e){for(;a.firstChild;)a.firstChild.remove();this._rows=[],this.dirtyTorrents=new Set(Object.keys(this._torrents)),document.querySelector("#reset").style.display=this.filterText.length>0?"block":"none"}let G=[],f=[];for(let Z of this._rows)this.dirtyTorrents.has(Z.getTorrentId())?f.push(Z):G.push(Z);for(let Z of f)Z.getElement().remove();let C=[];for(let Z of f){let L=Z.getTorrentId(),Q=this._torrents[L];Q&&Q.test(r,s,c,l)&&C.push(Z),this.dirtyTorrents.delete(L)}f=C;for(let Z of this.dirtyTorrents.values()){let L=this._torrents[Z];if(L&&L.test(r,s,c,l)){let Q=new ue(i,this,L),he=Q.getElement();he.row=Q,f.push(Q),he.addEventListener("click",this._onRowClicked.bind(this))}}this.sortRows(f);let h=[],y=G.length,U=f.length,H=document.createDocumentFragment(),O=0,z=0;for(;O!==y||z!==U;){let Z=null;if(O===y?Z=!1:z===U?Z=!0:Z=A.compareTorrents(G[O].getTorrent(),f[z].getTorrent(),t,o)<0,Z)h.push(G[O++]);else{let L=f[z++],Q=L.getElement();O===y?H.append(Q):a.insertBefore(Q,G[O].getElement()),h.push(L)}}a.append(H),this._rows=h,this.dirtyTorrents.clear(),this._updateStatusbar(),(I!==g()||m!==d())&&this._dispatchSelectionChanged()}setFilterTracker(e){let t=document.querySelector("#filter-tracker");t.value=e,this.filterTracker=e===p.FilterAll?"":e,this.refilterAllSoon()}_getTrackerCounts(){let e={};for(let t of this._getAllTorrents())for(let o of t.getTrackers()){let{sitename:r}=o;e[r]=(e[r]||0)+1}return e}setCurrentPopup(e,t=n.default_popup_level){for(let o=t;o{this.popup[t]&&(this.popup[t].removeEventListener("close",o),this.popup[t]=null)};this.popup[t].addEventListener("close",o)}else this.handler&&this.handler.classList.remove("selected")}};function Je(){let n=new j,e=new p,t=new q(e),o=new me(n,t,e),r=R(()=>o.elements.torrent_list.scrollTo(0,1));globalThis.addEventListener("load",r),globalThis.addEventListener("orientationchange",r)}document.addEventListener("DOMContentLoaded",Je);})(); //# sourceMappingURL=transmission-app.js.map