function markedMermaid(e){return{extensions:[{name:"mermaid",level:"block",start(e){return e.match(/^```mermaid/m)?.index},tokenizer(e,t){e=/^```mermaid\n([\s\S]*?)\n```/.exec(e);if(e)return{type:"mermaid",raw:e[0],text:e[1].trim()}},renderer(e){const t="mermaid-"+Math.random().toString(36).substr(2,9);e=`
| '+(r.oldNo||"")+' | '+(r.newNo||"")+' | '+("add"===r.kind?"+":"remove"===r.kind?"-":"hunk"===r.kind?"@":"")+' | '+s(r.text)+" |
',link:function(n,i){function e(){var e,t;n.file&&(n.kind=(e=n.file,"md"===(t=o(e&&e.filename))||"markdown"===t||e&&"Markdown"===e.language?"md":"code"),n.prismClass="language-"+(t=n.file,t&&t.language&&s[t.language.toLowerCase()]||s[o(t&&t.filename)]||"none"),r(()=>{i[0].querySelectorAll("pre code").forEach(e=>{window.Prism&&Prism.highlightElement(e)})},50))}n.$watch("file",e),n.$watch("file.content",e),n.$watch("terms",e),n.$watch("options",e,!0)}}}]).directive("markdown",["$location",function(r){return{restrict:"E",scope:{terms:"=",options:"=",content:"="},link:function(e,t,n){function i(){t.html(renderMD(e.content,r.url()+"/../"))}e.$watch(n.terms,i),e.$watch("terms",i),e.$watch("options",i),e.$watch("content",i)}}}]).directive("tree",[function(){return{restrict:"E",scope:{file:"=",parent:"@",searchQuery:"=",searchResults:"="},controller:["$element","$scope","$routeParams","$compile",function(n,g,i,r){if(g.repoId=document.location.pathname.split("/")[2],g.opens={},i.path){let t="";i.path.split("/").forEach(e=>{g.opens[t+"/"+e]=!0,t=t+"/"+e})}function s(e){var t,n=[];const i={"":{child:n}};for(t of e){if(t.path&&!i[t.path]){o=a=s=r=void 0;var r=t.path;if(!i[r]){var s=r.split("/");let t="";for(let e=0;eLoading GitHub info for "+e.repoId+"..."),r.get("/api/admin/repos/"+e.repoId+"/github").then(e=>{t&&(t.document.open(),t.document.write('
'+JSON.stringify(e.data,null,2).replace(/[<>]/g,e=>"<"===e?"<":">")+""),t.document.close())},e=>{e=e&&e.data?JSON.stringify(e.data,null,2):String(e);t&&(t.document.body.innerHTML='
'+e+"")})},i.statusCountFor=t=>{var e=(i.statusCounts||[]).find(e=>e._id===t);return e?e.count:0},i.statusStorageFor=t=>{var e=(i.statusCounts||[]).find(e=>e._id===t);return e?e.storage:0},i.isErrorsOnly=()=>i.query&&i.query.error&&!i.query.ready&&!i.query.preparing&&!i.query.expired&&!i.query.removed,i.toggleErrorsOnly=()=>{i.isErrorsOnly()?Object.assign(i.query,{ready:!1,preparing:!0,expired:!1,removed:!1,error:!0}):Object.assign(i.query,{ready:!1,preparing:!1,expired:!1,removed:!1,error:!0}),i.query.page=1},i.toggleSortDirection=()=>{i.query.direction="asc"===i.query.direction?"desc":"asc"},i.sortBy=e=>{i.query.sort===e?i.query.direction="asc"===i.query.direction?"desc":"asc":(i.query.sort=e,i.query.direction="desc"),i.query.page=1},i.sortIcon=e=>i.query.sort===e?"asc"===i.query.direction?"fa-arrow-up":"fa-arrow-down":"","admin.repos.filterPrefs");var n=loadFilterPrefs(o)||{},n=(i.query=Object.assign({},{page:1,limit:25,sort:"lastView",direction:"desc",search:"",owner:"",conference:"",dateFrom:"",dateTo:"",ready:!1,expired:!1,removed:!1,error:!0,preparing:!0},n,{page:1,search:""}),e.search());n.owner&&(i.query.owner=n.owner),n.conference&&(i.query.conference=n.conference),n.search&&(i.query.search=n.search);const a="admin.repos.presets";function l(){i.fetchError=null,r.get("/api/admin/repos",{params:i.query}).then(e=>{i.total=e.data.total,i.totalPage=Math.ceil(e.data.total/i.query.limit),i.repositories=e.data.results,i.statusCounts=e.data.statusCounts||[],i.totalSize=e.data.totalSize||0,i.allSelected=!1},e=>{i.fetchError=e&&e.data&&e.data.error||"Failed to load repositories",console.error(e)})}i.presets=JSON.parse(localStorage.getItem(a)||"[]"),i.savePreset=()=>{const t=window.prompt("Preset name:");var e;t&&(delete(e=Object.assign({},i.query)).page,i.presets=(i.presets||[]).filter(e=>e.name!==t),i.presets.push({name:t,query:e}),localStorage.setItem(a,JSON.stringify(i.presets)))},i.applyPreset=e=>{Object.assign(i.query,e.query,{page:1})},i.deletePreset=t=>{i.presets=(i.presets||[]).filter(e=>e.name!==t.name),localStorage.setItem(a,JSON.stringify(i.presets))},i.selectAllOnPage=()=>{i.allSelected=!i.allSelected,i.repositories.forEach(e=>{i.selected[e.repoId]=i.allSelected})},i.selectedCount=()=>Object.values(i.selected||{}).filter(Boolean).length,i.selectedRepos=()=>i.repositories.filter(e=>i.selected[e.repoId]),i.bulkRefresh=()=>{var e=i.selectedRepos();e.length&&confirm(`Force refresh ${e.length} repositories?`)&&e.forEach(e=>i.updateRepository(e))},i.bulkRemoveCache=()=>{var e=i.selectedRepos();e.length&&confirm(`Purge cache for ${e.length} repositories?`)&&e.forEach(e=>i.removeCache(e))},i.clearSelection=()=>{i.selected={},i.allSelected=!1},i.exportCsv=()=>{var e=new URLSearchParams(Object.entries(i.query).filter(([,e])=>""!==e&&!1!==e&&null!=e));e.set("format","csv"),e.set("limit","10000"),window.open("/api/admin/repos?"+e.toString(),"_blank")},i.removeCache=e=>{confirm("Remove cached files for "+e.repoId+"?")&&r.delete("/api/admin/repos/"+e.repoId).then(()=>l(),e=>console.error(e))},i.removeRepository=e=>{confirm("Remove repository "+e.repoId+"?")&&r.delete("/api/repo/"+e.repoId+"/").then(()=>l(),e=>console.error(e))},i.updateRepository=t=>{const n={title:`Refreshing ${t.repoId}...`,date:new Date,body:`The repository ${t.repoId} is going to be refreshed.`};i.toasts.push(n),r.post(`/api/repo/${t.repoId}/refresh`).then(e=>{"ready"==e.data.status?n.title=t.repoId+" is refreshed.":n.title=`Refreshing of ${t.repoId}.`},e=>{n.title=`Error during the refresh of ${t.repoId}.`,n.body=e.body})},i.fetchError=null,l();let c=null;i.$watch("query",()=>{clearTimeout(c),c=setTimeout(l,500);const{page:e,search:t,...n}=i.query;saveFilterPrefs(o,n),s()},!0),s()}]).controller("usersAdminController",["$scope","$http","$location",function(i,t,e){i.Math=Math,i.$watch("user.status",()=>{null==i.user&&e.url("/")}),null==i.user&&e.url("/"),i.users=[],i.total=-1,i.totalPage=0,i.statusCounts=[],i.selected={},i.allSelected=!1;const n=e=>{"/"===e.key&&!["INPUT","TEXTAREA","SELECT"].includes(document.activeElement?.tagName)&&(e.preventDefault(),e=document.querySelector('.admin-filter-toolbar input[type="search"]'))&&e.focus()},r=(document.addEventListener("keydown",n),i.$on("$destroy",()=>document.removeEventListener("keydown",n)),i.clearFilter=e=>{"dateRange"===e?(i.query.dateFrom="",i.query.dateTo=""):i.query[e]="",i.query.page=1},i.chips=[],()=>{var e=[];i.query.role&&e.push({key:"role",label:"Role",value:i.query.role}),i.chips=e}),s=(i.statusCountFor=t=>{var e=(i.statusCounts||[]).find(e=>e._id===t);return e?e.count:0},i.toggleSortDirection=()=>{i.query.direction="asc"===i.query.direction?"desc":"asc"},i.sortBy=e=>{i.query.sort===e?i.query.direction="asc"===i.query.direction?"desc":"asc":(i.query.sort=e,i.query.direction="desc"),i.query.page=1},i.sortIcon=e=>i.query.sort===e?"asc"===i.query.direction?"fa-arrow-up":"fa-arrow-down":"","admin.users.filterPrefs");var o=loadFilterPrefs(s)||{};function a(){i.fetchError=null,t.get("/api/admin/users",{params:i.query}).then(e=>{i.total=e.data.total,i.totalPage=Math.ceil(e.data.total/i.query.limit),i.users=e.data.results,i.statusCounts=e.data.statusCounts||[],i.allSelected=!1,i.$apply()},e=>{i.fetchError=e&&e.data&&e.data.error||"Failed to load users",console.error(e)})}i.query=Object.assign({},{page:1,limit:25,sort:"username",direction:"asc",search:"",status:"",role:"",dateFrom:"",dateTo:""},o,{page:1,search:""}),i.selectAllOnPage=()=>{i.allSelected=!i.allSelected,i.users.forEach(e=>{i.selected[e.username]=i.allSelected})},i.selectedCount=()=>Object.values(i.selected||{}).filter(Boolean).length,i.selectedUsers=()=>i.users.filter(e=>i.selected[e.username]),i.banUser=e=>{confirm(`Ban user ${e.username}?`)&&t.post(`/api/admin/users/${e.username}/ban`).then(a,e=>console.error(e))},i.activateUser=e=>{t.post(`/api/admin/users/${e.username}/activate`).then(a,e=>console.error(e))},i.bulkBan=()=>{var e=i.selectedUsers();e.length&&confirm(`Ban ${e.length} users?`)&&e.forEach(e=>i.banUser(e))},i.exportCsv=()=>{var e=new URLSearchParams(Object.entries(i.query).filter(([,e])=>""!==e&&!1!==e&&null!=e));e.set("format","csv"),e.set("limit","10000"),window.open("/api/admin/users?"+e.toString(),"_blank")},i.fetchError=null,a();let l=null;i.$watch("query",()=>{clearTimeout(l),l=setTimeout(a,500);const{page:e,search:t,...n}=i.query;saveFilterPrefs(s,n),r()},!0),r()}]).controller("userAdminController",["$scope","$http","$location","$routeParams",function(i,r,e,n){i.$watch("user.status",()=>{null==i.user&&e.url("/")}),null==i.user&&e.url("/"),i.userInfo,i.repositories=[],i.search="",i.selected={},i.allSelected=!1;const t="admin.user.filterPrefs",s={status:{ready:!0,expired:!0,removed:!0,error:!0,preparing:!0}},o="anonymizeDate",a="desc";var l=loadFilterPrefs(t)||{};function c(e){r.get("/api/admin/users/"+e+"/repos",{}).then(e=>{i.repositories=e.data},e=>{console.error(e)})}function h(e){r.get("/api/admin/users/"+e,{}).then(e=>{i.userInfo=e.data},e=>{console.error(e)})}function u(){r.get("/api/admin/tokens").then(e=>{i.tokens=e.data||[]},e=>{401!==e.status&&403!==e.status&&console.error(e)})}i.filters={status:Object.assign({},s.status,l.filters&&l.filters.status||{})},i.query={sort:l.sort||o,direction:l.direction||a},i.orderBy=("asc"===i.query.direction?"":"-")+i.query.sort,i.sortBy=e=>{i.query.sort===e?i.query.direction="asc"===i.query.direction?"desc":"asc":(i.query.sort=e,i.query.direction="desc"),i.orderBy=("asc"===i.query.direction?"":"-")+i.query.sort},i.sortIcon=e=>i.query.sort===e?"asc"===i.query.direction?"fa-arrow-up":"fa-arrow-down":"",i.$watch("query",()=>{saveFilterPrefs(t,{filters:i.filters,sort:i.query.sort,direction:i.query.direction})},!0),i.$watch("filters",()=>{saveFilterPrefs(t,{filters:i.filters,sort:i.query.sort,direction:i.query.direction})},!0),i.statusCountFor=t=>(i.repositories||[]).filter(e=>e.status===t).length,i.repoFiler=e=>0!=i.filters.status[e.status]&&(0==i.search.trim().length||-1
Loading GitHub info for "+e.repoId+"..."),r.get("/api/admin/repos/"+e.repoId+"/github").then(e=>{t&&(t.document.open(),t.document.write('
'+JSON.stringify(e.data,null,2).replace(/[<>]/g,e=>"<"===e?"<":">")+""),t.document.close())},e=>{e=e&&e.data?JSON.stringify(e.data,null,2):String(e);t&&(t.document.body.innerHTML='
'+e+"")})},h(n.username),c(n.username),i.banUser=()=>{confirm(`Ban user ${n.username}?`)&&r.post(`/api/admin/users/${n.username}/ban`).then(()=>h(n.username),e=>console.error(e))},i.activateUser=()=>{r.post(`/api/admin/users/${n.username}/activate`).then(()=>h(n.username),e=>console.error(e))},i.promoteUser=()=>{confirm(`Promote ${n.username} to admin?`)&&r.post(`/api/admin/users/${n.username}/promote`).then(()=>h(n.username),e=>console.error(e))},i.demoteUser=()=>{confirm(`Remove admin privileges from ${n.username}?`)&&r.post(`/api/admin/users/${n.username}/demote`).then(()=>h(n.username),e=>console.error(e))},i.tokens=[],i.tokenForm={name:"",plaintext:null},u(),i.createToken=()=>{i.tokenForm.name&&r.post("/api/admin/tokens",{name:i.tokenForm.name}).then(e=>{i.tokenForm.plaintext=e.data.token,i.tokenForm.name="",u()},e=>console.error(e))},i.revokeToken=e=>{confirm(`Revoke token "${e.name}"?`)&&r.delete("/api/admin/tokens/"+e.id).then(()=>u(),e=>console.error(e))},i.removeCache=e=>{confirm("Remove cached files for "+e.repoId+"?")&&r.delete("/api/admin/repos/"+e.repoId).then(()=>c(n.username),e=>console.error(e))},i.removeRepository=e=>{confirm("Remove repository "+e.repoId+"?")&&r.delete("/api/repo/"+e.repoId+"/").then(()=>c(n.username),e=>console.error(e))},i.updateRepository=t=>{const n={title:`Refreshing ${t.repoId}...`,date:new Date,body:`The repository ${t.repoId} is going to be refreshed.`};i.toasts.push(n),r.post(`/api/repo/${t.repoId}/refresh`).then(e=>{"ready"==e.data.status?n.title=t.repoId+" is refreshed.":n.title=`Refreshing of ${t.repoId}.`},e=>{n.title=`Error during the refresh of ${t.repoId}.`,n.body=e.body})},i.getGitHubRepositories=e=>{r.get(`/api/user/${i.userInfo.username}/all_repositories`,{params:{force:"1"}}).then(e=>{i.userInfo.repositories=e.data})};let d=null;i.$watch("query",()=>{clearTimeout(d),d=setTimeout(()=>{c(n.username)},500)},!0)}]).controller("conferencesAdminController",["$scope","$http","$location",function(i,t,e){i.Math=Math,i.$watch("user.status",()=>{null==i.user&&e.url("/")}),null==i.user&&e.url("/"),i.conferences=[],i.total=-1,i.totalPage=0,i.statusCounts=[];const n=e=>{"/"===e.key&&!["INPUT","TEXTAREA","SELECT"].includes(document.activeElement?.tagName)&&(e.preventDefault(),e=document.querySelector('.admin-filter-toolbar input[type="search"]'))&&e.focus()},r=(document.addEventListener("keydown",n),i.$on("$destroy",()=>document.removeEventListener("keydown",n)),i.clearFilter=e=>{"dateRange"===e?(i.query.dateFrom="",i.query.dateTo=""):i.query[e]="",i.query.page=1},i.chips=[],()=>{var e=[];(i.query.dateFrom||i.query.dateTo)&&e.push({key:"dateRange",label:"Date",value:(i.query.dateFrom||"…")+" – "+(i.query.dateTo||"…")}),i.chips=e}),s=(i.statusCountFor=t=>{var e=(i.statusCounts||[]).find(e=>e._id===t);return e?e.count:0},i.toggleSortDirection=()=>{i.query.direction="asc"===i.query.direction?"desc":"asc"},i.sortBy=e=>{i.query.sort===e?i.query.direction="asc"===i.query.direction?"desc":"asc":(i.query.sort=e,i.query.direction="desc"),i.query.page=1},i.sortIcon=e=>i.query.sort===e?"asc"===i.query.direction?"fa-arrow-up":"fa-arrow-down":"","admin.conferences.filterPrefs");var o=loadFilterPrefs(s)||{},o=(i.query=Object.assign({},{page:1,limit:25,sort:"name",direction:"asc",search:"",dateFrom:"",dateTo:"",ready:!1,expired:!1,removed:!1,error:!0,preparing:!0},o,{page:1,search:""}),e.search());o.search&&(i.query.search=o.search);const a="admin.conferences.presets";function l(){i.fetchError=null,t.get("/api/admin/conferences",{params:i.query}).then(e=>{i.total=e.data.total,i.totalPage=Math.ceil(e.data.total/i.query.limit),i.conferences=e.data.results,i.statusCounts=e.data.statusCounts||[]},e=>{i.fetchError=e&&e.data&&e.data.error||"Failed to load conferences",console.error(e)})}i.presets=JSON.parse(localStorage.getItem(a)||"[]"),i.savePreset=()=>{const t=window.prompt("Preset name:");var e;t&&(delete(e=Object.assign({},i.query)).page,i.presets=(i.presets||[]).filter(e=>e.name!==t),i.presets.push({name:t,query:e}),localStorage.setItem(a,JSON.stringify(i.presets)))},i.applyPreset=e=>{Object.assign(i.query,e.query,{page:1})},i.deletePreset=t=>{i.presets=(i.presets||[]).filter(e=>e.name!==t.name),localStorage.setItem(a,JSON.stringify(i.presets))},i.removeConference=e=>{confirm("Remove conference "+e.conferenceID+"?")&&t.delete("/api/admin/conferences/"+e.conferenceID).then(()=>l(),e=>console.error(e))},i.exportCsv=()=>{var e=new URLSearchParams(Object.entries(i.query).filter(([,e])=>""!==e&&!1!==e&&null!=e));e.set("format","csv"),e.set("limit","10000"),window.open("/api/admin/conferences?"+e.toString(),"_blank")},i.fetchError=null,l();let c=null;i.$watch("query",()=>{clearTimeout(c),c=setTimeout(l,500);const{page:e,search:t,...n}=i.query;saveFilterPrefs(s,n),r()},!0),r()}]).controller("queuesAdminController",["$scope","$http","$location","$interval","$timeout",function(R,t,e,n,i){function r(){var e={queue:R.selectedQueue,search:R.query.search};t.get("/api/admin/queues",{params:e}).then(e=>{R.queueList=e.data.queues||[],R.jobs=e.data.jobs||[],R.selectedStats=R.queueList.find(e=>e.key===R.selectedQueue)||R.queueList[0]||null},e=>console.error(e))}function s(){t.get("/api/admin/queues/metrics",{params:{queue:R.selectedQueue,range:R.range}}).then(e=>{R.metricsPoints=e.data.points||[],i(c,0)},e=>console.error(e))}R.$watch("user.status",()=>{null==R.user&&e.url("/")}),null==R.user&&e.url("/"),R.queueList=[],R.jobs=[],R.selectedQueue="download",R.selectedStats=null,R.range="1h",R.allStates=["active","waiting","delayed","failed","completed"],R.stateFilter={active:!0,waiting:!0,delayed:!0,failed:!0,completed:!0},R.query={search:"",autoRefresh:!0},R.filteredJobs=()=>(R.jobs||[]).filter(e=>R.stateFilter[e._state]),R.jobProgressPct=e=>e&&e.progress&&"object"==typeof e.progress&&"number"==typeof e.progress.percent?Math.max(0,Math.min(100,Math.round(e.progress.percent))):"number"==typeof e.progress?Math.max(0,Math.min(100,Math.round(e.progress))):null,R.jobDuration=e=>{return e.processedOn?(e=(e.finishedOn||Date.now())-e.processedOn)<1e3?e+"ms":(e/1e3).toFixed(1)+"s":"-"},R.metricsPoints=[],R.selectQueue=e=>{R.selectedQueue=e,r(),s()},R.setRange=e=>{R.range=e,s()},r(),s();const o=n(()=>{R.query.autoRefresh&&(r(),s())},15e3);function a(e){var t=e&&e.data&&(e.data.message||e.data.error)||"Request failed";R.actionError=t,i(()=>{R.actionError=null},5e3),console.error(e)}R.$on("$destroy",()=>n.cancel(o)),R.refreshNow=function(){r(),s()},R.actionError=null,R.removeJob=e=>{t.delete(`/api/admin/queue/${R.selectedQueue}/`+e.id).then(r,a)},R.retryJob=e=>{t.post(`/api/admin/queue/${R.selectedQueue}/`+e.id).then(r,a)},R.retryFailed=()=>{confirm(`Retry all failed jobs in ${R.selectedQueue}?`)&&t.post(`/api/admin/queue/${R.selectedQueue}/retry-failed`).then(r,e=>console.error(e))},R.drainSelected=()=>{confirm(`Drain the ${R.selectedQueue} queue?`)&&t.post(`/api/admin/queue/${R.selectedQueue}/drain`).then(r,e=>console.error(e))},R.togglePause=()=>{var e=R.selectedStats&&R.selectedStats.paused?"resume":"pause";t.post(`/api/admin/queue/${R.selectedQueue}/`+e).then(r,e=>console.error(e))},R.emptyQueue=()=>{confirm(`Empty the ${R.selectedQueue} queue? This removes ALL jobs.`)&&t.post(`/api/admin/queue/${R.selectedQueue}/empty`).then(r,e=>console.error(e))},R.pauseAll=()=>{confirm("Pause all queues?")&&t.post("/api/admin/queues/pause-all").then(r,e=>console.error(e))};let l=null;function M(e){if(e<=0)return{ticks:[0],niceMax:1};var t=Math.pow(10,Math.floor(Math.log10(e)));let n=t;e/n<2?n=t/2:5